diff options
Diffstat (limited to 'kernel/Documentation/networking/vrf.txt')
-rw-r--r-- | kernel/Documentation/networking/vrf.txt | 393 |
1 files changed, 393 insertions, 0 deletions
diff --git a/kernel/Documentation/networking/vrf.txt b/kernel/Documentation/networking/vrf.txt new file mode 100644 index 000000000..d52aa10cf --- /dev/null +++ b/kernel/Documentation/networking/vrf.txt @@ -0,0 +1,393 @@ +Virtual Routing and Forwarding (VRF) +==================================== +The VRF device combined with ip rules provides the ability to create virtual +routing and forwarding domains (aka VRFs, VRF-lite to be specific) in the +Linux network stack. One use case is the multi-tenancy problem where each +tenant has their own unique routing tables and in the very least need +different default gateways. + +Processes can be "VRF aware" by binding a socket to the VRF device. Packets +through the socket then use the routing table associated with the VRF +device. An important feature of the VRF device implementation is that it +impacts only Layer 3 and above so L2 tools (e.g., LLDP) are not affected +(ie., they do not need to be run in each VRF). The design also allows +the use of higher priority ip rules (Policy Based Routing, PBR) to take +precedence over the VRF device rules directing specific traffic as desired. + +In addition, VRF devices allow VRFs to be nested within namespaces. For +example network namespaces provide separation of network interfaces at L1 +(Layer 1 separation), VLANs on the interfaces within a namespace provide +L2 separation and then VRF devices provide L3 separation. + +Design +------ +A VRF device is created with an associated route table. Network interfaces +are then enslaved to a VRF device: + + +-----------------------------+ + | vrf-blue | ===> route table 10 + +-----------------------------+ + | | | + +------+ +------+ +-------------+ + | eth1 | | eth2 | ... | bond1 | + +------+ +------+ +-------------+ + | | + +------+ +------+ + | eth8 | | eth9 | + +------+ +------+ + +Packets received on an enslaved device and are switched to the VRF device +using an rx_handler which gives the impression that packets flow through +the VRF device. Similarly on egress routing rules are used to send packets +to the VRF device driver before getting sent out the actual interface. This +allows tcpdump on a VRF device to capture all packets into and out of the +VRF as a whole.[1] Similiarly, netfilter [2] and tc rules can be applied +using the VRF device to specify rules that apply to the VRF domain as a whole. + +[1] Packets in the forwarded state do not flow through the device, so those + packets are not seen by tcpdump. Will revisit this limitation in a + future release. + +[2] Iptables on ingress is limited to NF_INET_PRE_ROUTING only with skb->dev + set to real ingress device and egress is limited to NF_INET_POST_ROUTING. + Will revisit this limitation in a future release. + + +Setup +----- +1. VRF device is created with an association to a FIB table. + e.g, ip link add vrf-blue type vrf table 10 + ip link set dev vrf-blue up + +2. Rules are added that send lookups to the associated FIB table when the + iif or oif is the VRF device. e.g., + ip ru add oif vrf-blue table 10 + ip ru add iif vrf-blue table 10 + + Set the default route for the table (and hence default route for the VRF). + e.g, ip route add table 10 prohibit default + +3. Enslave L3 interfaces to a VRF device. + e.g, ip link set dev eth1 master vrf-blue + + Local and connected routes for enslaved devices are automatically moved to + the table associated with VRF device. Any additional routes depending on + the enslaved device will need to be reinserted following the enslavement. + +4. Additional VRF routes are added to associated table. + e.g., ip route add table 10 ... + + +Applications +------------ +Applications that are to work within a VRF need to bind their socket to the +VRF device: + + setsockopt(sd, SOL_SOCKET, SO_BINDTODEVICE, dev, strlen(dev)+1); + +or to specify the output device using cmsg and IP_PKTINFO. + + +Limitations +----------- +Index of original ingress interface is not available via cmsg. Will address +soon. + +################################################################################ + +Using iproute2 for VRFs +======================= +VRF devices do *not* have to start with 'vrf-'. That is a convention used here +for emphasis of the device type, similar to use of 'br' in bridge names. + +1. Create a VRF + + To instantiate a VRF device and associate it with a table: + $ ip link add dev NAME type vrf table ID + + Remember to add the ip rules as well: + $ ip ru add oif NAME table 10 + $ ip ru add iif NAME table 10 + $ ip -6 ru add oif NAME table 10 + $ ip -6 ru add iif NAME table 10 + + Without the rules route lookups are not directed to the table. + + For example: + $ ip link add dev vrf-blue type vrf table 10 + $ ip ru add pref 200 oif vrf-blue table 10 + $ ip ru add pref 200 iif vrf-blue table 10 + $ ip -6 ru add pref 200 oif vrf-blue table 10 + $ ip -6 ru add pref 200 iif vrf-blue table 10 + + +2. List VRFs + + To list VRFs that have been created: + $ ip [-d] link show type vrf + NOTE: The -d option is needed to show the table id + + For example: + $ ip -d link show type vrf + 11: vrf-mgmt: <NOARP,MASTER,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000 + link/ether 72:b3:ba:91:e2:24 brd ff:ff:ff:ff:ff:ff promiscuity 0 + vrf table 1 addrgenmode eui64 + 12: vrf-red: <NOARP,MASTER,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000 + link/ether b6:6f:6e:f6:da:73 brd ff:ff:ff:ff:ff:ff promiscuity 0 + vrf table 10 addrgenmode eui64 + 13: vrf-blue: <NOARP,MASTER,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000 + link/ether 36:62:e8:7d:bb:8c brd ff:ff:ff:ff:ff:ff promiscuity 0 + vrf table 66 addrgenmode eui64 + 14: vrf-green: <NOARP,MASTER,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000 + link/ether e6:28:b8:63:70:bb brd ff:ff:ff:ff:ff:ff promiscuity 0 + vrf table 81 addrgenmode eui64 + + + Or in brief output: + + $ ip -br link show type vrf + vrf-mgmt UP 72:b3:ba:91:e2:24 <NOARP,MASTER,UP,LOWER_UP> + vrf-red UP b6:6f:6e:f6:da:73 <NOARP,MASTER,UP,LOWER_UP> + vrf-blue UP 36:62:e8:7d:bb:8c <NOARP,MASTER,UP,LOWER_UP> + vrf-green UP e6:28:b8:63:70:bb <NOARP,MASTER,UP,LOWER_UP> + + +3. Assign a Network Interface to a VRF + + Network interfaces are assigned to a VRF by enslaving the netdevice to a + VRF device: + $ ip link set dev NAME master VRF-NAME + + On enslavement connected and local routes are automatically moved to the + table associated with the VRF device. + + For example: + $ ip link set dev eth0 master vrf-mgmt + + +4. Show Devices Assigned to a VRF + + To show devices that have been assigned to a specific VRF add the master + option to the ip command: + $ ip link show master VRF-NAME + + For example: + $ ip link show master vrf-red + 3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master vrf-red state UP mode DEFAULT group default qlen 1000 + link/ether 02:00:00:00:02:02 brd ff:ff:ff:ff:ff:ff + 4: eth2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master vrf-red state UP mode DEFAULT group default qlen 1000 + link/ether 02:00:00:00:02:03 brd ff:ff:ff:ff:ff:ff + 7: eth5: <BROADCAST,MULTICAST> mtu 1500 qdisc noop master vrf-red state DOWN mode DEFAULT group default qlen 1000 + link/ether 02:00:00:00:02:06 brd ff:ff:ff:ff:ff:ff + + + Or using the brief output: + $ ip -br link show master vrf-red + eth1 UP 02:00:00:00:02:02 <BROADCAST,MULTICAST,UP,LOWER_UP> + eth2 UP 02:00:00:00:02:03 <BROADCAST,MULTICAST,UP,LOWER_UP> + eth5 DOWN 02:00:00:00:02:06 <BROADCAST,MULTICAST> + + +5. Show Neighbor Entries for a VRF + + To list neighbor entries associated with devices enslaved to a VRF device + add the master option to the ip command: + $ ip [-6] neigh show master VRF-NAME + + For example: + $ ip neigh show master vrf-red + 10.2.1.254 dev eth1 lladdr a6:d9:c7:4f:06:23 REACHABLE + 10.2.2.254 dev eth2 lladdr 5e:54:01:6a:ee:80 REACHABLE + + $ ip -6 neigh show master vrf-red + 2002:1::64 dev eth1 lladdr a6:d9:c7:4f:06:23 REACHABLE + + +6. Show Addresses for a VRF + + To show addresses for interfaces associated with a VRF add the master + option to the ip command: + $ ip addr show master VRF-NAME + + For example: + $ ip addr show master vrf-red + 3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master vrf-red state UP group default qlen 1000 + link/ether 02:00:00:00:02:02 brd ff:ff:ff:ff:ff:ff + inet 10.2.1.2/24 brd 10.2.1.255 scope global eth1 + valid_lft forever preferred_lft forever + inet6 2002:1::2/120 scope global + valid_lft forever preferred_lft forever + inet6 fe80::ff:fe00:202/64 scope link + valid_lft forever preferred_lft forever + 4: eth2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master vrf-red state UP group default qlen 1000 + link/ether 02:00:00:00:02:03 brd ff:ff:ff:ff:ff:ff + inet 10.2.2.2/24 brd 10.2.2.255 scope global eth2 + valid_lft forever preferred_lft forever + inet6 2002:2::2/120 scope global + valid_lft forever preferred_lft forever + inet6 fe80::ff:fe00:203/64 scope link + valid_lft forever preferred_lft forever + 7: eth5: <BROADCAST,MULTICAST> mtu 1500 qdisc noop master vrf-red state DOWN group default qlen 1000 + link/ether 02:00:00:00:02:06 brd ff:ff:ff:ff:ff:ff + + Or in brief format: + $ ip -br addr show master vrf-red + eth1 UP 10.2.1.2/24 2002:1::2/120 fe80::ff:fe00:202/64 + eth2 UP 10.2.2.2/24 2002:2::2/120 fe80::ff:fe00:203/64 + eth5 DOWN + + +7. Show Routes for a VRF + + To show routes for a VRF use the ip command to display the table associated + with the VRF device: + $ ip [-6] route show table ID + + For example: + $ ip route show table vrf-red + prohibit default + broadcast 10.2.1.0 dev eth1 proto kernel scope link src 10.2.1.2 + 10.2.1.0/24 dev eth1 proto kernel scope link src 10.2.1.2 + local 10.2.1.2 dev eth1 proto kernel scope host src 10.2.1.2 + broadcast 10.2.1.255 dev eth1 proto kernel scope link src 10.2.1.2 + broadcast 10.2.2.0 dev eth2 proto kernel scope link src 10.2.2.2 + 10.2.2.0/24 dev eth2 proto kernel scope link src 10.2.2.2 + local 10.2.2.2 dev eth2 proto kernel scope host src 10.2.2.2 + broadcast 10.2.2.255 dev eth2 proto kernel scope link src 10.2.2.2 + + $ ip -6 route show table vrf-red + local 2002:1:: dev lo proto none metric 0 pref medium + local 2002:1::2 dev lo proto none metric 0 pref medium + 2002:1::/120 dev eth1 proto kernel metric 256 pref medium + local 2002:2:: dev lo proto none metric 0 pref medium + local 2002:2::2 dev lo proto none metric 0 pref medium + 2002:2::/120 dev eth2 proto kernel metric 256 pref medium + local fe80:: dev lo proto none metric 0 pref medium + local fe80:: dev lo proto none metric 0 pref medium + local fe80::ff:fe00:202 dev lo proto none metric 0 pref medium + local fe80::ff:fe00:203 dev lo proto none metric 0 pref medium + fe80::/64 dev eth1 proto kernel metric 256 pref medium + fe80::/64 dev eth2 proto kernel metric 256 pref medium + ff00::/8 dev vrf-red metric 256 pref medium + ff00::/8 dev eth1 metric 256 pref medium + ff00::/8 dev eth2 metric 256 pref medium + + +8. Route Lookup for a VRF + + A test route lookup can be done for a VRF by adding the oif option to ip: + $ ip [-6] route get oif VRF-NAME ADDRESS + + For example: + $ ip route get 10.2.1.40 oif vrf-red + 10.2.1.40 dev eth1 table vrf-red src 10.2.1.2 + cache + + $ ip -6 route get 2002:1::32 oif vrf-red + 2002:1::32 from :: dev eth1 table vrf-red proto kernel src 2002:1::2 metric 256 pref medium + + +9. Removing Network Interface from a VRF + + Network interfaces are removed from a VRF by breaking the enslavement to + the VRF device: + $ ip link set dev NAME nomaster + + Connected routes are moved back to the default table and local entries are + moved to the local table. + + For example: + $ ip link set dev eth0 nomaster + +-------------------------------------------------------------------------------- + +Commands used in this example: + +cat >> /etc/iproute2/rt_tables <<EOF +1 vrf-mgmt +10 vrf-red +66 vrf-blue +81 vrf-green +EOF + +function vrf_create +{ + VRF=$1 + TBID=$2 + # create VRF device + ip link add vrf-${VRF} type vrf table ${TBID} + + # add rules that direct lookups to vrf table + ip ru add pref 200 oif vrf-${VRF} table ${TBID} + ip ru add pref 200 iif vrf-${VRF} table ${TBID} + ip -6 ru add pref 200 oif vrf-${VRF} table ${TBID} + ip -6 ru add pref 200 iif vrf-${VRF} table ${TBID} + + if [ "${VRF}" != "mgmt" ]; then + ip route add table ${TBID} prohibit default + fi + ip link set dev vrf-${VRF} up + ip link set dev vrf-${VRF} state up +} + +vrf_create mgmt 1 +ip link set dev eth0 master vrf-mgmt + +vrf_create red 10 +ip link set dev eth1 master vrf-red +ip link set dev eth2 master vrf-red +ip link set dev eth5 master vrf-red + +vrf_create blue 66 +ip link set dev eth3 master vrf-blue + +vrf_create green 81 +ip link set dev eth4 master vrf-green + + +Interface addresses from /etc/network/interfaces: +auto eth0 +iface eth0 inet static + address 10.0.0.2 + netmask 255.255.255.0 + gateway 10.0.0.254 + +iface eth0 inet6 static + address 2000:1::2 + netmask 120 + +auto eth1 +iface eth1 inet static + address 10.2.1.2 + netmask 255.255.255.0 + +iface eth1 inet6 static + address 2002:1::2 + netmask 120 + +auto eth2 +iface eth2 inet static + address 10.2.2.2 + netmask 255.255.255.0 + +iface eth2 inet6 static + address 2002:2::2 + netmask 120 + +auto eth3 +iface eth3 inet static + address 10.2.3.2 + netmask 255.255.255.0 + +iface eth3 inet6 static + address 2002:3::2 + netmask 120 + +auto eth4 +iface eth4 inet static + address 10.2.4.2 + netmask 255.255.255.0 + +iface eth4 inet6 static + address 2002:4::2 + netmask 120 |