요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.
1. 요약·해설
원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.
2. 영어 원문 전체
번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.
원문 전체 펼치기
.. SPDX-License-Identifier: GPL-2.0
====================================
Virtual Routing and Forwarding (VRF)
====================================
The VRF Device
==============
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 the
device layer, 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
in the IPv4 and IPv6 processing stacks giving 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]_. Similarly, 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 supports PREROUTING with skb->dev set to the real
ingress device and both INPUT and PREROUTING rules with skb->dev set to
the VRF device. For egress POSTROUTING and OUTPUT rules can be written
using either the VRF device or real egress device.
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. An l3mdev FIB rule directs lookups to the table associated with the device.
A single l3mdev rule is sufficient for all VRFs. The VRF device adds the
l3mdev rule for IPv4 and IPv6 when the first device is created with a
default preference of 1000. Users may delete the rule if desired and add
with a different priority or install per-VRF rules.
Prior to the v4.8 kernel iif and oif rules are needed for each VRF device::
ip ru add oif vrf-blue table 10
ip ru add iif vrf-blue table 10
3. Set the default route for the table (and hence default route for the VRF)::
ip route add table 10 unreachable default metric 4278198272
This high metric value ensures that the default unreachable route can
be overridden by a routing protocol suite. FRRouting interprets
kernel metrics as a combined admin distance (upper byte) and priority
(lower 3 bytes). Thus the above metric translates to [255/8192].
4. Enslave L3 interfaces to a VRF device::
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 are dropped and will need to be reinserted to the VRF
FIB table following the enslavement.
The IPv6 sysctl option keep_addr_on_down can be enabled to keep IPv6 global
addresses as VRF enslavement changes::
sysctl -w net.ipv6.conf.all.keep_addr_on_down=1
5. Additional VRF routes are added to associated table::
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.
By default the scope of the port bindings for unbound sockets is
limited to the default VRF. That is, it will not be matched by packets
arriving on interfaces enslaved to an l3mdev and processes may bind to
the same port if they bind to an l3mdev.
TCP & UDP services running in the default VRF context (ie., not bound
to any VRF device) can work across all VRF domains by enabling the
tcp_l3mdev_accept and udp_l3mdev_accept sysctl options::
sysctl -w net.ipv4.tcp_l3mdev_accept=1
sysctl -w net.ipv4.udp_l3mdev_accept=1
These options are disabled by default so that a socket in a VRF is only
selected for packets in that VRF. There is a similar option for RAW
sockets, which is enabled by default for reasons of backwards compatibility.
This is so as to specify the output device with cmsg and IP_PKTINFO, but
using a socket not bound to the corresponding VRF. This allows e.g. older ping
implementations to be run with specifying the device but without executing it
in the VRF. This option can be disabled so that packets received in a VRF
context are only handled by a raw socket bound to the VRF, and packets in the
default VRF are only handled by a socket not bound to any VRF::
sysctl -w net.ipv4.raw_l3mdev_accept=0
netfilter rules on the VRF device can be used to limit access to services
running in the default VRF context as well.
Using VRF-aware applications (applications which simultaneously create sockets
outside and inside VRFs) in conjunction with ``net.ipv4.tcp_l3mdev_accept=1``
is possible but may lead to problems in some situations. With that sysctl
value, it is unspecified which listening socket will be selected to handle
connections for VRF traffic; ie. either a socket bound to the VRF or an unbound
socket may be used to accept new connections from a VRF. This somewhat
unexpected behavior can lead to problems if sockets are configured with extra
options (ex. TCP MD5 keys) with the expectation that VRF traffic will
exclusively be handled by sockets bound to VRFs, as would be the case with
``net.ipv4.tcp_l3mdev_accept=0``. Finally and as a reminder, regardless of
which listening socket is selected, established sockets will be created in the
VRF based on the ingress interface, as documented earlier.
--------------------------------------------------------------------------------
Using iproute2 for VRFs
=======================
iproute2 supports the vrf keyword as of v4.7. For backwards compatibility this
section lists both commands where appropriate -- with the vrf keyword and the
older form without it.
1. Create a VRF
To instantiate a VRF device and associate it with a table::
$ ip link add dev NAME type vrf table ID
As of v4.8 the kernel supports the l3mdev FIB rule where a single rule
covers all VRFs. The l3mdev rule is created for IPv4 and IPv6 on first
device create.
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: 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: 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: 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: 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
mgmt UP 72:b3:ba:91:e2:24 <NOARP,MASTER,UP,LOWER_UP>
red UP b6:6f:6e:f6:da:73 <NOARP,MASTER,UP,LOWER_UP>
blue UP 36:62:e8:7d:bb:8c <NOARP,MASTER,UP,LOWER_UP>
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 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 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 vrf NAME
$ ip link show master NAME
For example::
$ ip link show vrf red
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master 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 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 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 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 vrf NAME
$ ip [-6] neigh show master NAME
For example::
$ ip neigh show 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 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 vrf NAME
$ ip addr show master NAME
For example::
$ ip addr show vrf red
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master 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 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 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 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 vrf NAME
$ ip [-6] route show table ID
For example::
$ ip route show vrf red
unreachable default metric 4278198272
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 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 red metric 256 pref medium
ff00::/8 dev eth1 metric 256 pref medium
ff00::/8 dev eth2 metric 256 pref medium
unreachable default dev lo metric 4278198272 error -101 pref medium
8. Route Lookup for a VRF
A test route lookup can be done for a VRF::
$ ip [-6] route get vrf NAME ADDRESS
$ ip [-6] route get oif NAME ADDRESS
For example::
$ ip route get 10.2.1.40 vrf red
10.2.1.40 dev eth1 table red src 10.2.1.2
cache
$ ip -6 route get 2002:1::32 vrf red
2002:1::32 from :: dev eth1 table 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.d/vrf.conf <<EOF
1 mgmt
10 red
66 blue
81 green
EOF
function vrf_create
{
VRF=$1
TBID=$2
# create VRF device
ip link add ${VRF} type vrf table ${TBID}
if [ "${VRF}" != "mgmt" ]; then
ip route add table ${TBID} unreachable default metric 4278198272
fi
ip link set dev ${VRF} up
}
vrf_create mgmt 1
ip link set dev eth0 master mgmt
vrf_create red 10
ip link set dev eth1 master red
ip link set dev eth2 master red
ip link set dev eth5 master red
vrf_create blue 66
ip link set dev eth3 master blue
vrf_create green 81
ip link set dev eth4 master 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
3. 한국어 전문 번역
영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.
VRF device 개요
1-29VRF device와 ip rule을 결합하면 Linux network stack에 virtual routing and forwarding domain, 구체적으로 VRF-lite를 만들 수 있습니다. 대표 용도는 tenant마다 고유 routing table과 최소한 서로 다른 default gateway가 필요한 multi-tenancy입니다.
Process가 socket을 VRF device에 bind하면 VRF-aware가 됩니다. 그 socket의 packet은 VRF device에 연결된 routing table을 사용합니다.
VRF 구현은 Layer 3 이상에만 영향을 주므로 LLDP 같은 L2 tool은 영향받지 않고 VRF마다 따로 실행할 필요가 없습니다. 더 높은 priority의 Policy Based Routing(PBR) ip rule을 VRF rule보다 앞세워 특정 traffic을 별도로 보낼 수도 있습니다.
VRF는 network namespace 안에 중첩할 수 있습니다. Namespace가 device layer의 interface 분리, 그 안의 VLAN이 L2 분리, VRF device가 L3 분리를 담당하는 계층 구조를 만들 수 있습니다.
.. SPDX-License-Identifier: GPL-2.0
====================================
Virtual Routing and Forwarding (VRF)
====================================
The VRF Device
==============
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 the
device layer, VLANs on the interfaces within a namespace provide L2 separation
and then VRF devices provide L3 separation.
Design
Device와 packet path 설계
30-63VRF device는 연관 route table과 함께 생성하고 실제 network interface를 그 VRF의 slave로 붙입니다. 원문 예에서는 `vrf-blue`가 route table 10을 사용하며 `eth1`, `eth2`, `bond1`이 속하고 `bond1` 아래에는 `eth8`과 `eth9`가 있습니다.
원문 ASCII topology를 같은 master/slave 구조로 정리했습니다.
Slave device로 들어온 packet은 IPv4/IPv6 processing stack에서 VRF device로 전환되어 VRF를 통과하는 것처럼 보입니다. Egress에서도 routing rule이 실제 interface로 보내기 전에 packet을 VRF driver로 보냅니다.
이 설계 덕분에 VRF device의 `tcpdump`가 VRF 전체 ingress와 egress packet을 포착하고, netfilter와 tc rule도 VRF domain 전체에 적용할 수 있습니다. 다만 forwarded state의 packet은 device를 통과하지 않아 `tcpdump`에 보이지 않는 현재 제한이 있습니다.
Ingress iptables에서는 실제 ingress device인 `skb->dev`로 PREROUTING을 볼 수 있고 VRF device인 `skb->dev`로 INPUT과 PREROUTING rule을 쓸 수 있습니다. Egress POSTROUTING과 OUTPUT은 VRF device 또는 실제 egress device를 사용할 수 있습니다.
------
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
in the IPv4 and IPv6 processing stacks giving 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]_. Similarly, 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 supports PREROUTING with skb->dev set to the real
ingress device and both INPUT and PREROUTING rules with skb->dev set to
the VRF device. For egress POSTROUTING and OUTPUT rules can be written
using either the VRF device or real egress device.
VRF 생성과 FIB 설정
64-110먼저 `ip link add vrf-blue type vrf table 10`으로 FIB table 10에 연결된 VRF를 만들고 device를 up 상태로 설정합니다.
하나의 `l3mdev` FIB rule이면 모든 VRF lookup을 각 device의 table로 보낼 수 있습니다. 첫 VRF 생성 때 IPv4와 IPv6 rule이 preference 1000으로 추가됩니다. 사용자는 이를 지우고 다른 priority로 다시 만들거나 VRF별 rule을 설치할 수 있습니다. Kernel v4.8 이전에는 각 VRF마다 iif와 oif rule이 필요합니다.
Table 10의 기본 route는 `unreachable default metric 4278198272`로 설정합니다. 높은 metric은 routing protocol suite가 이 unreachable route를 덮어쓸 수 있게 합니다. FRRouting은 kernel metric의 상위 byte를 admin distance, 하위 3 bytes를 priority로 해석하므로 이 값은 `[255/8192]`가 됩니다.
`ip link set dev eth1 master vrf-blue`로 L3 interface를 VRF에 enslave합니다. Local route와 connected route는 VRF table로 자동 이동하지만 slave device에 의존하는 추가 route는 삭제되므로 enslavement 뒤 VRF FIB table에 다시 넣어야 합니다.
VRF enslavement 변화 중 IPv6 global address를 유지하려면 `net.ipv6.conf.all.keep_addr_on_down=1`을 설정합니다. 추가 VRF route는 연결된 table 10에 넣습니다.
Device, rule, default route, slave와 추가 route를 순서대로 구성합니다.
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. An l3mdev FIB rule directs lookups to the table associated with the device.
A single l3mdev rule is sufficient for all VRFs. The VRF device adds the
l3mdev rule for IPv4 and IPv6 when the first device is created with a
default preference of 1000. Users may delete the rule if desired and add
with a different priority or install per-VRF rules.
Prior to the v4.8 kernel iif and oif rules are needed for each VRF device::
ip ru add oif vrf-blue table 10
ip ru add iif vrf-blue table 10
3. Set the default route for the table (and hence default route for the VRF)::
ip route add table 10 unreachable default metric 4278198272
This high metric value ensures that the default unreachable route can
be overridden by a routing protocol suite. FRRouting interprets
kernel metrics as a combined admin distance (upper byte) and priority
(lower 3 bytes). Thus the above metric translates to [255/8192].
4. Enslave L3 interfaces to a VRF device::
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 are dropped and will need to be reinserted to the VRF
FIB table following the enslavement.
The IPv6 sysctl option keep_addr_on_down can be enabled to keep IPv6 global
addresses as VRF enslavement changes::
sysctl -w net.ipv6.conf.all.keep_addr_on_down=1
5. Additional VRF routes are added to associated table::
ip route add table 10 ...
Application socket과 service 선택
111-160VRF 안에서 동작할 application은 `SO_BINDTODEVICE`로 socket을 VRF device에 bind하거나 CMSG의 `IP_PKTINFO`로 output device를 지정합니다.
기본적으로 unbound socket의 port binding scope는 default VRF로 제한됩니다. L3 master에 enslave된 interface로 들어온 packet과 match하지 않으며, process는 l3mdev에 bind하면 같은 port를 별도로 사용할 수 있습니다.
Default VRF에서 실행되는 TCP/UDP service가 모든 VRF domain을 처리하게 하려면 `net.ipv4.tcp_l3mdev_accept=1`과 `net.ipv4.udp_l3mdev_accept=1`을 설정합니다. 기본값은 disabled이므로 보통 VRF packet은 해당 VRF의 socket만 선택합니다.
RAW socket용 `raw_l3mdev_accept`는 호환성을 위해 기본 enabled입니다. 그래서 오래된 ping도 VRF에 bind되지 않은 socket에서 CMSG와 `IP_PKTINFO`로 device를 지정할 수 있습니다. 0으로 끄면 VRF packet은 VRF-bound raw socket만, default VRF packet은 unbound socket만 처리합니다.
VRF device의 netfilter rule로 default VRF service 접근을 제한할 수도 있습니다.
VRF-aware application과 `tcp_l3mdev_accept=1`을 함께 쓰면 VRF-bound listener와 unbound listener 중 어느 socket이 새 VRF connection을 받을지 정의되지 않습니다. TCP MD5 key처럼 socket별 option이 다르면 예상과 다른 listener 선택이 문제가 될 수 있습니다. `tcp_l3mdev_accept=0`이면 VRF-bound socket이 독점합니다. 어느 listener가 선택되든 established socket은 ingress interface에 따른 VRF 안에서 생성됩니다.
Default VRF socket이 다른 VRF traffic을 받을 수 있는지 제어합니다.
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.
By default the scope of the port bindings for unbound sockets is
limited to the default VRF. That is, it will not be matched by packets
arriving on interfaces enslaved to an l3mdev and processes may bind to
the same port if they bind to an l3mdev.
TCP & UDP services running in the default VRF context (ie., not bound
to any VRF device) can work across all VRF domains by enabling the
tcp_l3mdev_accept and udp_l3mdev_accept sysctl options::
sysctl -w net.ipv4.tcp_l3mdev_accept=1
sysctl -w net.ipv4.udp_l3mdev_accept=1
These options are disabled by default so that a socket in a VRF is only
selected for packets in that VRF. There is a similar option for RAW
sockets, which is enabled by default for reasons of backwards compatibility.
This is so as to specify the output device with cmsg and IP_PKTINFO, but
using a socket not bound to the corresponding VRF. This allows e.g. older ping
implementations to be run with specifying the device but without executing it
in the VRF. This option can be disabled so that packets received in a VRF
context are only handled by a raw socket bound to the VRF, and packets in the
default VRF are only handled by a socket not bound to any VRF::
sysctl -w net.ipv4.raw_l3mdev_accept=0
netfilter rules on the VRF device can be used to limit access to services
running in the default VRF context as well.
Using VRF-aware applications (applications which simultaneously create sockets
outside and inside VRFs) in conjunction with ``net.ipv4.tcp_l3mdev_accept=1``
is possible but may lead to problems in some situations. With that sysctl
value, it is unspecified which listening socket will be selected to handle
connections for VRF traffic; ie. either a socket bound to the VRF or an unbound
socket may be used to accept new connections from a VRF. This somewhat
unexpected behavior can lead to problems if sockets are configured with extra
options (ex. TCP MD5 keys) with the expectation that VRF traffic will
exclusively be handled by sockets bound to VRFs, as would be the case with
``net.ipv4.tcp_l3mdev_accept=0``. Finally and as a reminder, regardless of
which listening socket is selected, established sockets will be created in the
VRF based on the ingress interface, as documented earlier.
--------------------------------------------------------------------------------
iproute2로 생성·목록·interface 할당
161-252iproute2는 v4.7부터 `vrf` keyword를 지원합니다. 문서는 호환성을 위해 keyword 방식과 이전 형식을 함께 제시합니다.
`ip link add dev NAME type vrf table ID`로 VRF device를 만들고 table과 연결합니다. Kernel v4.8부터 첫 VRF 생성 시 IPv4와 IPv6에 모든 VRF를 포괄하는 단일 l3mdev FIB rule을 생성합니다.
생성된 VRF는 `ip -d link show type vrf`로 나열합니다. `-d`가 있어야 table ID가 보이며 예제는 mgmt/table 1, red/10, blue/66, green/81을 보여 줍니다. `ip -br link show type vrf`는 간략 형식입니다.
Network interface는 `ip link set dev NAME master NAME`으로 VRF device에 enslave합니다. 이때 connected route와 local route가 연관 VRF table로 자동 이동합니다.
특정 VRF에 할당된 device는 `ip link show vrf NAME` 또는 이전 형식인 `ip link show master NAME`으로 봅니다. `-br`을 추가하면 interface 상태와 address를 한 줄씩 표시합니다.
Using iproute2 for VRFs
=======================
iproute2 supports the vrf keyword as of v4.7. For backwards compatibility this
section lists both commands where appropriate -- with the vrf keyword and the
older form without it.
1. Create a VRF
To instantiate a VRF device and associate it with a table::
$ ip link add dev NAME type vrf table ID
As of v4.8 the kernel supports the l3mdev FIB rule where a single rule
covers all VRFs. The l3mdev rule is created for IPv4 and IPv6 on first
device create.
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: 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: 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: 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: 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
mgmt UP 72:b3:ba:91:e2:24 <NOARP,MASTER,UP,LOWER_UP>
red UP b6:6f:6e:f6:da:73 <NOARP,MASTER,UP,LOWER_UP>
blue UP 36:62:e8:7d:bb:8c <NOARP,MASTER,UP,LOWER_UP>
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 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 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 vrf NAME
$ ip link show master NAME
For example::
$ ip link show vrf red
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master 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 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 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 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>
Neighbor와 address 조회
253-308VRF slave device에 연결된 neighbor entry는 `ip [-6] neigh show vrf NAME` 또는 `ip [-6] neigh show master NAME`으로 나열합니다. 예제는 red VRF의 IPv4 neighbor 두 개와 IPv6 neighbor 하나를 보여 줍니다.
VRF interface의 address는 `ip addr show vrf NAME` 또는 `ip addr show master NAME`으로 확인합니다. 예제의 red VRF에는 eth1과 eth2의 IPv4 global, IPv6 global·link-local address가 있고 eth5는 down 상태입니다.
`ip -br addr show vrf red`는 같은 정보를 interface별 상태와 address list로 압축해 보여 줍니다.
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 vrf NAME
$ ip [-6] neigh show master NAME
For example::
$ ip neigh show 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 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 vrf NAME
$ ip addr show master NAME
For example::
$ ip addr show vrf red
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master 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 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 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 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
Route 표시·lookup·slave 제거
309-378VRF route는 `ip [-6] route show vrf NAME` 또는 연결된 `table ID`를 표시해 봅니다. IPv4 예제에는 metric 4278198272의 unreachable default와 eth1·eth2의 broadcast, connected, local route가 있습니다.
IPv6 예제에는 두 interface의 global·link-local route, VRF와 slave의 multicast route, 마지막 unreachable default가 포함됩니다.
시험 route lookup은 `ip [-6] route get vrf NAME ADDRESS` 또는 `ip [-6] route get oif NAME ADDRESS`로 수행합니다. 예제는 red table에서 IPv4 destination을 eth1과 source 10.2.1.2로, IPv6 destination을 eth1과 source 2002:1::2로 선택합니다.
`ip link set dev NAME nomaster`로 enslavement를 끊어 interface를 VRF에서 제거합니다. Connected route는 default table로, local entry는 local table로 돌아갑니다.
할당과 route 이동, 제거 후 복귀를 연결합니다.
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 vrf NAME
$ ip [-6] route show table ID
For example::
$ ip route show vrf red
unreachable default metric 4278198272
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 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 red metric 256 pref medium
ff00::/8 dev eth1 metric 256 pref medium
ff00::/8 dev eth2 metric 256 pref medium
unreachable default dev lo metric 4278198272 error -101 pref medium
8. Route Lookup for a VRF
A test route lookup can be done for a VRF::
$ ip [-6] route get vrf NAME ADDRESS
$ ip [-6] route get oif NAME ADDRESS
For example::
$ ip route get 10.2.1.40 vrf red
10.2.1.40 dev eth1 table red src 10.2.1.2
cache
$ ip -6 route get 2002:1::32 vrf red
2002:1::32 from :: dev eth1 table 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
전체 example configuration
379-464전체 예제는 `/etc/iproute2/rt_tables.d/vrf.conf`에 mgmt=1, red=10, blue=66, green=81 table mapping을 추가합니다.
Shell function `vrf_create`는 이름과 table ID를 받아 VRF device를 만들고, mgmt가 아닌 VRF에는 metric 4278198272의 unreachable default를 넣은 뒤 device를 up으로 설정합니다.
그 다음 eth0은 mgmt, eth1·eth2·eth5는 red, eth3은 blue, eth4는 green의 slave로 배치합니다.
`/etc/network/interfaces` 예제는 eth0에 10.0.0.2/24와 2000:1::2/120, eth1에 10.2.1.2/24와 2002:1::2/120, eth2에 10.2.2.2/24와 2002:2::2/120, eth3에 10.2.3.2/24와 2002:3::2/120, eth4에 10.2.4.2/24와 2002:4::2/120을 설정합니다. eth0에는 IPv4 gateway 10.0.0.254도 둡니다.
원문의 table, interface, address 배치를 요약합니다.
--------------------------------------------------------------------------------
Commands used in this example::
cat >> /etc/iproute2/rt_tables.d/vrf.conf <<EOF
1 mgmt
10 red
66 blue
81 green
EOF
function vrf_create
{
VRF=$1
TBID=$2
# create VRF device
ip link add ${VRF} type vrf table ${TBID}
if [ "${VRF}" != "mgmt" ]; then
ip route add table ${TBID} unreachable default metric 4278198272
fi
ip link set dev ${VRF} up
}
vrf_create mgmt 1
ip link set dev eth0 master mgmt
vrf_create red 10
ip link set dev eth1 master red
ip link set dev eth2 master red
ip link set dev eth5 master red
vrf_create blue 66
ip link set dev eth3 master blue
vrf_create green 81
ip link set dev eth4 master 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
요약·해설
vrf.rst:1-464VRF device는 interface를 하나의 L3 routing domain과 FIB table에 묶습니다. 하나의 l3mdev rule로 여러 VRF를 처리하며 namespace와 VLAN 안에 중첩해 device·L2·L3 격리를 조합할 수 있습니다.
Application은 socket을 VRF device에 bind하거나 IP_PKTINFO로 output device를 지정합니다. Default-VRF service의 교차 VRF 수신은 l3mdev_accept sysctl이 제어하며 listener option 차이가 있다면 socket 선택의 모호성을 주의해야 합니다.
Slave ingress와 routing table, VRF-aware socket을 연결합니다.