← Documents Documentation/networking/vrf.rst GitHub 원문 ↗

Linux 6.18.37 · Networking

Virtual Routing and Forwarding (VRF)

Linux VRF-lite의 L3 routing domain, l3mdev FIB rule, socket binding과 iproute2 운영 절차를 설명합니다.

Source pathDocumentation/networking/vrf.rst
Source versionLinux v6.18.37
TranslationDUJINLABS 전문 번역 + 해설

요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.

1. 요약·해설

원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.

요약·해설

vrf.rst:1-464

VRF 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 선택의 모호성을 주의해야 합니다.

VRF packet path
Slave interface ingressVRF L3 masterl3mdev FIB ruleVRF route tableVRF-bound socket 또는 egress slave

Slave ingress와 routing table, VRF-aware socket을 연결합니다.

2. 영어 원문 전체

번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.

원문 전체 펼치기
1 .. SPDX-License-Identifier: GPL-2.0
2
3 ====================================
4 Virtual Routing and Forwarding (VRF)
5 ====================================
6
7 The VRF Device
8 ==============
9
10 The VRF device combined with ip rules provides the ability to create virtual
11 routing and forwarding domains (aka VRFs, VRF-lite to be specific) in the
12 Linux network stack. One use case is the multi-tenancy problem where each
13 tenant has their own unique routing tables and in the very least need
14 different default gateways.
15
16 Processes can be "VRF aware" by binding a socket to the VRF device. Packets
17 through the socket then use the routing table associated with the VRF
18 device. An important feature of the VRF device implementation is that it
19 impacts only Layer 3 and above so L2 tools (e.g., LLDP) are not affected
20 (ie., they do not need to be run in each VRF). The design also allows
21 the use of higher priority ip rules (Policy Based Routing, PBR) to take
22 precedence over the VRF device rules directing specific traffic as desired.
23
24 In addition, VRF devices allow VRFs to be nested within namespaces. For
25 example network namespaces provide separation of network interfaces at the
26 device layer, VLANs on the interfaces within a namespace provide L2 separation
27 and then VRF devices provide L3 separation.
28
29 Design
30 ------
31 A VRF device is created with an associated route table. Network interfaces
32 are then enslaved to a VRF device::
33
34 +-----------------------------+
35 | vrf-blue | ===> route table 10
36 +-----------------------------+
37 | | |
38 +------+ +------+ +-------------+
39 | eth1 | | eth2 | ... | bond1 |
40 +------+ +------+ +-------------+
41 | |
42 +------+ +------+
43 | eth8 | | eth9 |
44 +------+ +------+
45
46 Packets received on an enslaved device and are switched to the VRF device
47 in the IPv4 and IPv6 processing stacks giving the impression that packets
48 flow through the VRF device. Similarly on egress routing rules are used to
49 send packets to the VRF device driver before getting sent out the actual
50 interface. This allows tcpdump on a VRF device to capture all packets into
51 and out of the VRF as a whole\ [1]_. Similarly, netfilter\ [2]_ and tc rules
52 can be applied using the VRF device to specify rules that apply to the VRF
53 domain as a whole.
54
55 .. [1] Packets in the forwarded state do not flow through the device, so those
56 packets are not seen by tcpdump. Will revisit this limitation in a
57 future release.
58
59 .. [2] Iptables on ingress supports PREROUTING with skb->dev set to the real
60 ingress device and both INPUT and PREROUTING rules with skb->dev set to
61 the VRF device. For egress POSTROUTING and OUTPUT rules can be written
62 using either the VRF device or real egress device.
63
64 Setup
65 -----
66 1. VRF device is created with an association to a FIB table.
67 e.g,::
68
69 ip link add vrf-blue type vrf table 10
70 ip link set dev vrf-blue up
71
72 2. An l3mdev FIB rule directs lookups to the table associated with the device.
73 A single l3mdev rule is sufficient for all VRFs. The VRF device adds the
74 l3mdev rule for IPv4 and IPv6 when the first device is created with a
75 default preference of 1000. Users may delete the rule if desired and add
76 with a different priority or install per-VRF rules.
77
78 Prior to the v4.8 kernel iif and oif rules are needed for each VRF device::
79
80 ip ru add oif vrf-blue table 10
81 ip ru add iif vrf-blue table 10
82
83 3. Set the default route for the table (and hence default route for the VRF)::
84
85 ip route add table 10 unreachable default metric 4278198272
86
87 This high metric value ensures that the default unreachable route can
88 be overridden by a routing protocol suite. FRRouting interprets
89 kernel metrics as a combined admin distance (upper byte) and priority
90 (lower 3 bytes). Thus the above metric translates to [255/8192].
91
92 4. Enslave L3 interfaces to a VRF device::
93
94 ip link set dev eth1 master vrf-blue
95
96 Local and connected routes for enslaved devices are automatically moved to
97 the table associated with VRF device. Any additional routes depending on
98 the enslaved device are dropped and will need to be reinserted to the VRF
99 FIB table following the enslavement.
100
101 The IPv6 sysctl option keep_addr_on_down can be enabled to keep IPv6 global
102 addresses as VRF enslavement changes::
103
104 sysctl -w net.ipv6.conf.all.keep_addr_on_down=1
105
106 5. Additional VRF routes are added to associated table::
107
108 ip route add table 10 ...
109
110
111 Applications
112 ------------
113 Applications that are to work within a VRF need to bind their socket to the
114 VRF device::
115
116 setsockopt(sd, SOL_SOCKET, SO_BINDTODEVICE, dev, strlen(dev)+1);
117
118 or to specify the output device using cmsg and IP_PKTINFO.
119
120 By default the scope of the port bindings for unbound sockets is
121 limited to the default VRF. That is, it will not be matched by packets
122 arriving on interfaces enslaved to an l3mdev and processes may bind to
123 the same port if they bind to an l3mdev.
124
125 TCP & UDP services running in the default VRF context (ie., not bound
126 to any VRF device) can work across all VRF domains by enabling the
127 tcp_l3mdev_accept and udp_l3mdev_accept sysctl options::
128
129 sysctl -w net.ipv4.tcp_l3mdev_accept=1
130 sysctl -w net.ipv4.udp_l3mdev_accept=1
131
132 These options are disabled by default so that a socket in a VRF is only
133 selected for packets in that VRF. There is a similar option for RAW
134 sockets, which is enabled by default for reasons of backwards compatibility.
135 This is so as to specify the output device with cmsg and IP_PKTINFO, but
136 using a socket not bound to the corresponding VRF. This allows e.g. older ping
137 implementations to be run with specifying the device but without executing it
138 in the VRF. This option can be disabled so that packets received in a VRF
139 context are only handled by a raw socket bound to the VRF, and packets in the
140 default VRF are only handled by a socket not bound to any VRF::
141
142 sysctl -w net.ipv4.raw_l3mdev_accept=0
143
144 netfilter rules on the VRF device can be used to limit access to services
145 running in the default VRF context as well.
146
147 Using VRF-aware applications (applications which simultaneously create sockets
148 outside and inside VRFs) in conjunction with ``net.ipv4.tcp_l3mdev_accept=1``
149 is possible but may lead to problems in some situations. With that sysctl
150 value, it is unspecified which listening socket will be selected to handle
151 connections for VRF traffic; ie. either a socket bound to the VRF or an unbound
152 socket may be used to accept new connections from a VRF. This somewhat
153 unexpected behavior can lead to problems if sockets are configured with extra
154 options (ex. TCP MD5 keys) with the expectation that VRF traffic will
155 exclusively be handled by sockets bound to VRFs, as would be the case with
156 ``net.ipv4.tcp_l3mdev_accept=0``. Finally and as a reminder, regardless of
157 which listening socket is selected, established sockets will be created in the
158 VRF based on the ingress interface, as documented earlier.
159
160 --------------------------------------------------------------------------------
161
162 Using iproute2 for VRFs
163 =======================
164 iproute2 supports the vrf keyword as of v4.7. For backwards compatibility this
165 section lists both commands where appropriate -- with the vrf keyword and the
166 older form without it.
167
168 1. Create a VRF
169
170 To instantiate a VRF device and associate it with a table::
171
172 $ ip link add dev NAME type vrf table ID
173
174 As of v4.8 the kernel supports the l3mdev FIB rule where a single rule
175 covers all VRFs. The l3mdev rule is created for IPv4 and IPv6 on first
176 device create.
177
178 2. List VRFs
179
180 To list VRFs that have been created::
181
182 $ ip [-d] link show type vrf
183 NOTE: The -d option is needed to show the table id
184
185 For example::
186
187 $ ip -d link show type vrf
188 11: mgmt: <NOARP,MASTER,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000
189 link/ether 72:b3:ba:91:e2:24 brd ff:ff:ff:ff:ff:ff promiscuity 0
190 vrf table 1 addrgenmode eui64
191 12: red: <NOARP,MASTER,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000
192 link/ether b6:6f:6e:f6:da:73 brd ff:ff:ff:ff:ff:ff promiscuity 0
193 vrf table 10 addrgenmode eui64
194 13: blue: <NOARP,MASTER,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000
195 link/ether 36:62:e8:7d:bb:8c brd ff:ff:ff:ff:ff:ff promiscuity 0
196 vrf table 66 addrgenmode eui64
197 14: green: <NOARP,MASTER,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000
198 link/ether e6:28:b8:63:70:bb brd ff:ff:ff:ff:ff:ff promiscuity 0
199 vrf table 81 addrgenmode eui64
200
201
202 Or in brief output::
203
204 $ ip -br link show type vrf
205 mgmt UP 72:b3:ba:91:e2:24 <NOARP,MASTER,UP,LOWER_UP>
206 red UP b6:6f:6e:f6:da:73 <NOARP,MASTER,UP,LOWER_UP>
207 blue UP 36:62:e8:7d:bb:8c <NOARP,MASTER,UP,LOWER_UP>
208 green UP e6:28:b8:63:70:bb <NOARP,MASTER,UP,LOWER_UP>
209
210
211 3. Assign a Network Interface to a VRF
212
213 Network interfaces are assigned to a VRF by enslaving the netdevice to a
214 VRF device::
215
216 $ ip link set dev NAME master NAME
217
218 On enslavement connected and local routes are automatically moved to the
219 table associated with the VRF device.
220
221 For example::
222
223 $ ip link set dev eth0 master mgmt
224
225
226 4. Show Devices Assigned to a VRF
227
228 To show devices that have been assigned to a specific VRF add the master
229 option to the ip command::
230
231 $ ip link show vrf NAME
232 $ ip link show master NAME
233
234 For example::
235
236 $ ip link show vrf red
237 3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master red state UP mode DEFAULT group default qlen 1000
238 link/ether 02:00:00:00:02:02 brd ff:ff:ff:ff:ff:ff
239 4: eth2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master red state UP mode DEFAULT group default qlen 1000
240 link/ether 02:00:00:00:02:03 brd ff:ff:ff:ff:ff:ff
241 7: eth5: <BROADCAST,MULTICAST> mtu 1500 qdisc noop master red state DOWN mode DEFAULT group default qlen 1000
242 link/ether 02:00:00:00:02:06 brd ff:ff:ff:ff:ff:ff
243
244
245 Or using the brief output::
246
247 $ ip -br link show vrf red
248 eth1 UP 02:00:00:00:02:02 <BROADCAST,MULTICAST,UP,LOWER_UP>
249 eth2 UP 02:00:00:00:02:03 <BROADCAST,MULTICAST,UP,LOWER_UP>
250 eth5 DOWN 02:00:00:00:02:06 <BROADCAST,MULTICAST>
251
252
253 5. Show Neighbor Entries for a VRF
254
255 To list neighbor entries associated with devices enslaved to a VRF device
256 add the master option to the ip command::
257
258 $ ip [-6] neigh show vrf NAME
259 $ ip [-6] neigh show master NAME
260
261 For example::
262
263 $ ip neigh show vrf red
264 10.2.1.254 dev eth1 lladdr a6:d9:c7:4f:06:23 REACHABLE
265 10.2.2.254 dev eth2 lladdr 5e:54:01:6a:ee:80 REACHABLE
266
267 $ ip -6 neigh show vrf red
268 2002:1::64 dev eth1 lladdr a6:d9:c7:4f:06:23 REACHABLE
269
270
271 6. Show Addresses for a VRF
272
273 To show addresses for interfaces associated with a VRF add the master
274 option to the ip command::
275
276 $ ip addr show vrf NAME
277 $ ip addr show master NAME
278
279 For example::
280
281 $ ip addr show vrf red
282 3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master red state UP group default qlen 1000
283 link/ether 02:00:00:00:02:02 brd ff:ff:ff:ff:ff:ff
284 inet 10.2.1.2/24 brd 10.2.1.255 scope global eth1
285 valid_lft forever preferred_lft forever
286 inet6 2002:1::2/120 scope global
287 valid_lft forever preferred_lft forever
288 inet6 fe80::ff:fe00:202/64 scope link
289 valid_lft forever preferred_lft forever
290 4: eth2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master red state UP group default qlen 1000
291 link/ether 02:00:00:00:02:03 brd ff:ff:ff:ff:ff:ff
292 inet 10.2.2.2/24 brd 10.2.2.255 scope global eth2
293 valid_lft forever preferred_lft forever
294 inet6 2002:2::2/120 scope global
295 valid_lft forever preferred_lft forever
296 inet6 fe80::ff:fe00:203/64 scope link
297 valid_lft forever preferred_lft forever
298 7: eth5: <BROADCAST,MULTICAST> mtu 1500 qdisc noop master red state DOWN group default qlen 1000
299 link/ether 02:00:00:00:02:06 brd ff:ff:ff:ff:ff:ff
300
301 Or in brief format::
302
303 $ ip -br addr show vrf red
304 eth1 UP 10.2.1.2/24 2002:1::2/120 fe80::ff:fe00:202/64
305 eth2 UP 10.2.2.2/24 2002:2::2/120 fe80::ff:fe00:203/64
306 eth5 DOWN
307
308
309 7. Show Routes for a VRF
310
311 To show routes for a VRF use the ip command to display the table associated
312 with the VRF device::
313
314 $ ip [-6] route show vrf NAME
315 $ ip [-6] route show table ID
316
317 For example::
318
319 $ ip route show vrf red
320 unreachable default metric 4278198272
321 broadcast 10.2.1.0 dev eth1 proto kernel scope link src 10.2.1.2
322 10.2.1.0/24 dev eth1 proto kernel scope link src 10.2.1.2
323 local 10.2.1.2 dev eth1 proto kernel scope host src 10.2.1.2
324 broadcast 10.2.1.255 dev eth1 proto kernel scope link src 10.2.1.2
325 broadcast 10.2.2.0 dev eth2 proto kernel scope link src 10.2.2.2
326 10.2.2.0/24 dev eth2 proto kernel scope link src 10.2.2.2
327 local 10.2.2.2 dev eth2 proto kernel scope host src 10.2.2.2
328 broadcast 10.2.2.255 dev eth2 proto kernel scope link src 10.2.2.2
329
330 $ ip -6 route show vrf red
331 local 2002:1:: dev lo proto none metric 0 pref medium
332 local 2002:1::2 dev lo proto none metric 0 pref medium
333 2002:1::/120 dev eth1 proto kernel metric 256 pref medium
334 local 2002:2:: dev lo proto none metric 0 pref medium
335 local 2002:2::2 dev lo proto none metric 0 pref medium
336 2002:2::/120 dev eth2 proto kernel metric 256 pref medium
337 local fe80:: dev lo proto none metric 0 pref medium
338 local fe80:: dev lo proto none metric 0 pref medium
339 local fe80::ff:fe00:202 dev lo proto none metric 0 pref medium
340 local fe80::ff:fe00:203 dev lo proto none metric 0 pref medium
341 fe80::/64 dev eth1 proto kernel metric 256 pref medium
342 fe80::/64 dev eth2 proto kernel metric 256 pref medium
343 ff00::/8 dev red metric 256 pref medium
344 ff00::/8 dev eth1 metric 256 pref medium
345 ff00::/8 dev eth2 metric 256 pref medium
346 unreachable default dev lo metric 4278198272 error -101 pref medium
347
348 8. Route Lookup for a VRF
349
350 A test route lookup can be done for a VRF::
351
352 $ ip [-6] route get vrf NAME ADDRESS
353 $ ip [-6] route get oif NAME ADDRESS
354
355 For example::
356
357 $ ip route get 10.2.1.40 vrf red
358 10.2.1.40 dev eth1 table red src 10.2.1.2
359 cache
360
361 $ ip -6 route get 2002:1::32 vrf red
362 2002:1::32 from :: dev eth1 table red proto kernel src 2002:1::2 metric 256 pref medium
363
364
365 9. Removing Network Interface from a VRF
366
367 Network interfaces are removed from a VRF by breaking the enslavement to
368 the VRF device::
369
370 $ ip link set dev NAME nomaster
371
372 Connected routes are moved back to the default table and local entries are
373 moved to the local table.
374
375 For example::
376
377 $ ip link set dev eth0 nomaster
378
379 --------------------------------------------------------------------------------
380
381 Commands used in this example::
382
383 cat >> /etc/iproute2/rt_tables.d/vrf.conf <<EOF
384 1 mgmt
385 10 red
386 66 blue
387 81 green
388 EOF
389
390 function vrf_create
391 {
392 VRF=$1
393 TBID=$2
394
395 # create VRF device
396 ip link add ${VRF} type vrf table ${TBID}
397
398 if [ "${VRF}" != "mgmt" ]; then
399 ip route add table ${TBID} unreachable default metric 4278198272
400 fi
401 ip link set dev ${VRF} up
402 }
403
404 vrf_create mgmt 1
405 ip link set dev eth0 master mgmt
406
407 vrf_create red 10
408 ip link set dev eth1 master red
409 ip link set dev eth2 master red
410 ip link set dev eth5 master red
411
412 vrf_create blue 66
413 ip link set dev eth3 master blue
414
415 vrf_create green 81
416 ip link set dev eth4 master green
417
418
419 Interface addresses from /etc/network/interfaces:
420 auto eth0
421 iface eth0 inet static
422 address 10.0.0.2
423 netmask 255.255.255.0
424 gateway 10.0.0.254
425
426 iface eth0 inet6 static
427 address 2000:1::2
428 netmask 120
429
430 auto eth1
431 iface eth1 inet static
432 address 10.2.1.2
433 netmask 255.255.255.0
434
435 iface eth1 inet6 static
436 address 2002:1::2
437 netmask 120
438
439 auto eth2
440 iface eth2 inet static
441 address 10.2.2.2
442 netmask 255.255.255.0
443
444 iface eth2 inet6 static
445 address 2002:2::2
446 netmask 120
447
448 auto eth3
449 iface eth3 inet static
450 address 10.2.3.2
451 netmask 255.255.255.0
452
453 iface eth3 inet6 static
454 address 2002:3::2
455 netmask 120
456
457 auto eth4
458 iface eth4 inet static
459 address 10.2.4.2
460 netmask 255.255.255.0
461
462 iface eth4 inet6 static
463 address 2002:4::2
464 netmask 120
465

3. 한국어 전문 번역

영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.

VRF device 개요

1-29

VRF 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-63

VRF device는 연관 route table과 함께 생성하고 실제 network interface를 그 VRF의 slave로 붙입니다. 원문 예에서는 `vrf-blue`가 route table 10을 사용하며 `eth1`, `eth2`, `bond1`이 속하고 `bond1` 아래에는 `eth8`과 `eth9`가 있습니다.

vrf-blue topology
vrf-blueroute table 10eth1
vrf-blueroute table 10eth2
vrf-blueroute table 10bond1eth8
vrf-blueroute table 10bond1eth9

원문 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에 넣습니다.

VRF setup 단계
단계핵심 명령·효과
1VRF device + FIB table 생성
2l3mdev rule로 lookup 연결
3높은 metric의 unreachable default
4L3 interface를 master에 enslave
5추가 route를 VRF table에 삽입

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-160

VRF 안에서 동작할 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 안에서 생성됩니다.

l3mdev accept sysctl
Option기본값활성화 효과
tcp_l3mdev_accept0Unbound TCP listener가 모든 VRF에서 선택될 수 있음
udp_l3mdev_accept0Unbound UDP service가 모든 VRF 처리
raw_l3mdev_accept1Unbound raw socket에서 IP_PKTINFO device 지정 허용

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-252

iproute2는 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-308

VRF 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-378

VRF 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로 돌아갑니다.

VRF interface lifecycle
Interface default domainmaster VRF 지정Connected/local route가 VRF table로 이동VRF route lookupnomasterDefault/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도 둡니다.

Example VRF mapping
VRF/tableInterfaces주요 address
mgmt/1eth010.0.0.2, 2000:1::2
red/10eth1, eth2, eth510.2.1.2, 10.2.2.2 및 대응 IPv6
blue/66eth310.2.3.2, 2002:3::2
green/81eth410.2.4.2, 2002:4::2

원문의 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