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

Linux 6.18.37 · Networking

Universal TUN/TAP device driver

Userspace virtual network interface인 TUN/TAP의 device 생성, frame format, multiqueue API와 tunnel 동작을 설명합니다.

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

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

1. 요약·해설

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

요약·해설

tuntap.rst:1-259

TUN/TAP은 kernel network stack과 userspace program 사이에서 packet을 주고받는 virtual interface입니다. TUN은 IP packet, TAP은 Ethernet frame을 사용하며 `/dev/net/tun`을 열고 `TUNSETIFF`로 interface를 등록합니다.

`IFF_MULTI_QUEUE`를 사용하면 같은 device에 여러 file descriptor queue를 붙여 병렬 송수신할 수 있습니다. Queue는 `TUNSETQUEUE`와 attach/detach flag로 동적으로 제어합니다.

TUN/TAP data path
Kernel network stacktunXX IP 또는 tapXX Ethernet/dev/net/tun fdUserspace tunnel/bridgeTCP·UDP 또는 다른 interface

Kernel과 userspace가 virtual file descriptor를 통해 packet을 교환합니다.

2. 영어 원문 전체

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

원문 전체 펼치기
1 .. SPDX-License-Identifier: GPL-2.0
2 .. include:: <isonum.txt>
3
4 ===============================
5 Universal TUN/TAP device driver
6 ===============================
7
8 Copyright |copy| 1999-2000 Maxim Krasnyansky <[email protected]>
9
10 Linux, Solaris drivers
11 Copyright |copy| 1999-2000 Maxim Krasnyansky <[email protected]>
12
13 FreeBSD TAP driver
14 Copyright |copy| 1999-2000 Maksim Yevmenkin <[email protected]>
15
16 Revision of this document 2002 by Florian Thiel <[email protected]>
17
18 1. Description
19 ==============
20
21 TUN/TAP provides packet reception and transmission for user space programs.
22 It can be seen as a simple Point-to-Point or Ethernet device, which,
23 instead of receiving packets from physical media, receives them from
24 user space program and instead of sending packets via physical media
25 writes them to the user space program.
26
27 In order to use the driver a program has to open /dev/net/tun and issue a
28 corresponding ioctl() to register a network device with the kernel. A network
29 device will appear as tunXX or tapXX, depending on the options chosen. When
30 the program closes the file descriptor, the network device and all
31 corresponding routes will disappear.
32
33 Depending on the type of device chosen the userspace program has to read/write
34 IP packets (with tun) or ethernet frames (with tap). Which one is being used
35 depends on the flags given with the ioctl().
36
37 The package from http://vtun.sourceforge.net/tun contains two simple examples
38 for how to use tun and tap devices. Both programs work like a bridge between
39 two network interfaces.
40 br_select.c - bridge based on select system call.
41 br_sigio.c - bridge based on async io and SIGIO signal.
42 However, the best example is VTun http://vtun.sourceforge.net :))
43
44 2. Configuration
45 ================
46
47 Create device node::
48
49 mkdir /dev/net (if it doesn't exist already)
50 mknod /dev/net/tun c 10 200
51
52 Set permissions::
53
54 e.g. chmod 0666 /dev/net/tun
55
56 There's no harm in allowing the device to be accessible by non-root users,
57 since CAP_NET_ADMIN is required for creating network devices or for
58 connecting to network devices which aren't owned by the user in question.
59 If you want to create persistent devices and give ownership of them to
60 unprivileged users, then you need the /dev/net/tun device to be usable by
61 those users.
62
63 Driver module autoloading
64
65 Make sure that "Kernel module loader" - module auto-loading
66 support is enabled in your kernel. The kernel should load it on
67 first access.
68
69 Manual loading
70
71 insert the module by hand::
72
73 modprobe tun
74
75 If you do it the latter way, you have to load the module every time you
76 need it, if you do it the other way it will be automatically loaded when
77 /dev/net/tun is being opened.
78
79 3. Program interface
80 ====================
81
82 3.1 Network device allocation
83 -----------------------------
84
85 ``char *dev`` should be the name of the device with a format string (e.g.
86 "tun%d"), but (as far as I can see) this can be any valid network device name.
87 Note that the character pointer becomes overwritten with the real device name
88 (e.g. "tun0")::
89
90 #include <linux/if.h>
91 #include <linux/if_tun.h>
92
93 int tun_alloc(char *dev)
94 {
95 struct ifreq ifr;
96 int fd, err;
97
98 if( (fd = open("/dev/net/tun", O_RDWR)) < 0 )
99 return tun_alloc_old(dev);
100
101 memset(&ifr, 0, sizeof(ifr));
102
103 /* Flags: IFF_TUN - TUN device (no Ethernet headers)
104 * IFF_TAP - TAP device
105 *
106 * IFF_NO_PI - Do not provide packet information
107 */
108 ifr.ifr_flags = IFF_TUN;
109 if( *dev )
110 strscpy_pad(ifr.ifr_name, dev, IFNAMSIZ);
111
112 if( (err = ioctl(fd, TUNSETIFF, (void *) &ifr)) < 0 ){
113 close(fd);
114 return err;
115 }
116 strcpy(dev, ifr.ifr_name);
117 return fd;
118 }
119
120 3.2 Frame format
121 ----------------
122
123 If flag IFF_NO_PI is not set each frame format is::
124
125 Flags [2 bytes]
126 Proto [2 bytes]
127 Raw protocol(IP, IPv6, etc) frame.
128
129 3.3 Multiqueue tuntap interface
130 -------------------------------
131
132 From version 3.8, Linux supports multiqueue tuntap which can uses multiple
133 file descriptors (queues) to parallelize packets sending or receiving. The
134 device allocation is the same as before, and if user wants to create multiple
135 queues, TUNSETIFF with the same device name must be called many times with
136 IFF_MULTI_QUEUE flag.
137
138 ``char *dev`` should be the name of the device, queues is the number of queues
139 to be created, fds is used to store and return the file descriptors (queues)
140 created to the caller. Each file descriptor were served as the interface of a
141 queue which could be accessed by userspace.
142
143 ::
144
145 #include <linux/if.h>
146 #include <linux/if_tun.h>
147
148 int tun_alloc_mq(char *dev, int queues, int *fds)
149 {
150 struct ifreq ifr;
151 int fd, err, i;
152
153 if (!dev)
154 return -1;
155
156 memset(&ifr, 0, sizeof(ifr));
157 /* Flags: IFF_TUN - TUN device (no Ethernet headers)
158 * IFF_TAP - TAP device
159 *
160 * IFF_NO_PI - Do not provide packet information
161 * IFF_MULTI_QUEUE - Create a queue of multiqueue device
162 */
163 ifr.ifr_flags = IFF_TAP | IFF_NO_PI | IFF_MULTI_QUEUE;
164 strcpy(ifr.ifr_name, dev);
165
166 for (i = 0; i < queues; i++) {
167 if ((fd = open("/dev/net/tun", O_RDWR)) < 0)
168 goto err;
169 err = ioctl(fd, TUNSETIFF, (void *)&ifr);
170 if (err) {
171 close(fd);
172 goto err;
173 }
174 fds[i] = fd;
175 }
176
177 return 0;
178 err:
179 for (--i; i >= 0; i--)
180 close(fds[i]);
181 return err;
182 }
183
184 A new ioctl(TUNSETQUEUE) were introduced to enable or disable a queue. When
185 calling it with IFF_DETACH_QUEUE flag, the queue were disabled. And when
186 calling it with IFF_ATTACH_QUEUE flag, the queue were enabled. The queue were
187 enabled by default after it was created through TUNSETIFF.
188
189 fd is the file descriptor (queue) that we want to enable or disable, when
190 enable is true we enable it, otherwise we disable it::
191
192 #include <linux/if.h>
193 #include <linux/if_tun.h>
194
195 int tun_set_queue(int fd, int enable)
196 {
197 struct ifreq ifr;
198
199 memset(&ifr, 0, sizeof(ifr));
200
201 if (enable)
202 ifr.ifr_flags = IFF_ATTACH_QUEUE;
203 else
204 ifr.ifr_flags = IFF_DETACH_QUEUE;
205
206 return ioctl(fd, TUNSETQUEUE, (void *)&ifr);
207 }
208
209 Universal TUN/TAP device driver Frequently Asked Question
210 =========================================================
211
212 1. What platforms are supported by TUN/TAP driver ?
213
214 Currently driver has been written for 3 Unices:
215
216 - Linux kernels 2.2.x, 2.4.x
217 - FreeBSD 3.x, 4.x, 5.x
218 - Solaris 2.6, 7.0, 8.0
219
220 2. What is TUN/TAP driver used for?
221
222 As mentioned above, main purpose of TUN/TAP driver is tunneling.
223 It is used by VTun (http://vtun.sourceforge.net).
224
225 Another interesting application using TUN/TAP is pipsecd
226 (http://perso.enst.fr/~beyssac/pipsec/), a userspace IPSec
227 implementation that can use complete kernel routing (unlike FreeS/WAN).
228
229 3. How does Virtual network device actually work ?
230
231 Virtual network device can be viewed as a simple Point-to-Point or
232 Ethernet device, which instead of receiving packets from a physical
233 media, receives them from user space program and instead of sending
234 packets via physical media sends them to the user space program.
235
236 Let's say that you configured IPv6 on the tap0, then whenever
237 the kernel sends an IPv6 packet to tap0, it is passed to the application
238 (VTun for example). The application encrypts, compresses and sends it to
239 the other side over TCP or UDP. The application on the other side decompresses
240 and decrypts the data received and writes the packet to the TAP device,
241 the kernel handles the packet like it came from real physical device.
242
243 4. What is the difference between TUN driver and TAP driver?
244
245 TUN works with IP frames. TAP works with Ethernet frames.
246
247 This means that you have to read/write IP packets when you are using tun and
248 ethernet frames when using tap.
249
250 5. What is the difference between BPF and TUN/TAP driver?
251
252 BPF is an advanced packet filter. It can be attached to existing
253 network interface. It does not provide a virtual network interface.
254 A TUN/TAP driver does provide a virtual network interface and it is possible
255 to attach BPF to this interface.
256
257 6. Does TAP driver support kernel Ethernet bridging?
258
259 Yes. Linux and FreeBSD drivers support Ethernet bridging.
260

3. 한국어 전문 번역

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

문서와 구현의 유래

1-17

이 문서는 GPL-2.0 license를 따르는 Universal TUN/TAP device driver 설명서입니다. Linux와 Solaris driver는 Maxim Krasnyansky, FreeBSD TAP driver는 Maksim Yevmenkin의 1999~2000년 저작물이며, Florian Thiel이 2002년에 문서를 개정했습니다.

.. SPDX-License-Identifier: GPL-2.0
.. include:: <isonum.txt>

===============================
Universal TUN/TAP device driver
===============================

Copyright |copy| 1999-2000 Maxim Krasnyansky <[email protected]>

  Linux, Solaris drivers
  Copyright |copy| 1999-2000 Maxim Krasnyansky <[email protected]>

  FreeBSD TAP driver
  Copyright |copy| 1999-2000 Maksim Yevmenkin <[email protected]>

  Revision of this document 2002 by Florian Thiel <[email protected]>

TUN/TAP 동작 개요

18-43

TUN/TAP은 userspace program에 packet 수신과 송신 기능을 제공합니다. 단순한 Point-to-Point 또는 Ethernet device처럼 보이지만 physical media 대신 userspace program에서 packet을 받고, physical media로 보내는 대신 userspace program에 packet을 써 줍니다.

Driver를 사용하려면 program이 `/dev/net/tun`을 열고 해당 `ioctl()`을 호출해 kernel에 network device를 등록합니다. 선택한 option에 따라 `tunXX` 또는 `tapXX` device가 나타나며, program이 file descriptor를 닫으면 network device와 관련 route가 모두 사라집니다.

선택한 device type에 따라 userspace는 TUN에서는 IP packet을, TAP에서는 Ethernet frame을 읽고 써야 합니다. 어느 형식인지는 `ioctl()`에 넘긴 flag가 결정합니다.

원문은 TUN/TAP 사용 예제로 VTun package의 `br_select.c`와 `br_sigio.c`를 소개합니다. 전자는 `select` system call 기반 bridge이고 후자는 async I/O와 `SIGIO` signal 기반 bridge입니다. 더 완전한 예는 VTun 자체입니다.

TUN과 TAP의 packet 단위
DeviceKernel에 보이는 형태Userspace frame
TUNPoint-to-Point interfaceIP/IPv6 packet
TAPEthernet interfaceEthernet frame

Userspace가 file descriptor에서 읽고 쓰는 protocol 계층입니다.

1. Description
==============

  TUN/TAP provides packet reception and transmission for user space programs.
  It can be seen as a simple Point-to-Point or Ethernet device, which,
  instead of receiving packets from physical media, receives them from
  user space program and instead of sending packets via physical media
  writes them to the user space program.

  In order to use the driver a program has to open /dev/net/tun and issue a
  corresponding ioctl() to register a network device with the kernel. A network
  device will appear as tunXX or tapXX, depending on the options chosen. When
  the program closes the file descriptor, the network device and all
  corresponding routes will disappear.

  Depending on the type of device chosen the userspace program has to read/write
  IP packets (with tun) or ethernet frames (with tap). Which one is being used
  depends on the flags given with the ioctl().

  The package from http://vtun.sourceforge.net/tun contains two simple examples
  for how to use tun and tap devices. Both programs work like a bridge between
  two network interfaces.
  br_select.c - bridge based on select system call.
  br_sigio.c  - bridge based on async io and SIGIO signal.
  However, the best example is VTun http://vtun.sourceforge.net :))

Device node와 module 구성

44-78

먼저 `/dev/net` directory가 없다면 만들고 major 10, minor 200인 character device `/dev/net/tun`을 생성합니다. 예시는 `chmod 0666 /dev/net/tun`으로 permission을 설정합니다.

일반 user가 device node에 접근하도록 허용해도 network device 생성이나 자신이 소유하지 않은 device 연결에는 `CAP_NET_ADMIN`이 필요하므로 그 자체로 해롭지 않습니다. Unprivileged user가 소유할 persistent device를 만들려면 해당 user가 `/dev/net/tun`을 사용할 수 있어야 합니다.

Kernel에서 module auto-loading을 활성화하면 `/dev/net/tun` 최초 접근 때 driver module을 자동으로 load합니다.

수동 방식은 `modprobe tun`으로 module을 삽입합니다. 이 경우 필요할 때마다 직접 load해야 하지만, auto-loading 방식에서는 `/dev/net/tun`을 열 때 자동으로 load됩니다.

TUN/TAP driver 준비
/dev/net/tun c 10:200permissiontun module auto/manual loadopen()TUNSETIFF

Device node 접근과 module loading 이후 interface를 생성합니다.

2. Configuration
================

  Create device node::

     mkdir /dev/net (if it doesn't exist already)
     mknod /dev/net/tun c 10 200

  Set permissions::

     e.g. chmod 0666 /dev/net/tun

  There's no harm in allowing the device to be accessible by non-root users,
  since CAP_NET_ADMIN is required for creating network devices or for
  connecting to network devices which aren't owned by the user in question.
  If you want to create persistent devices and give ownership of them to
  unprivileged users, then you need the /dev/net/tun device to be usable by
  those users.

  Driver module autoloading

     Make sure that "Kernel module loader" - module auto-loading
     support is enabled in your kernel.  The kernel should load it on
     first access.

  Manual loading

     insert the module by hand::

        modprobe tun

  If you do it the latter way, you have to load the module every time you
  need it, if you do it the other way it will be automatically loaded when
  /dev/net/tun is being opened.

Network device 할당 API

79-119

`char *dev`에는 `tun%d` 같은 format string으로 device name을 전달하지만 유효한 network device name이라면 사용할 수 있습니다. 호출 뒤 이 buffer는 `tun0` 같은 실제 device name으로 덮어써집니다.

예제 `tun_alloc()`은 `/dev/net/tun`을 `O_RDWR`로 열고 `struct ifreq`를 초기화합니다. `IFF_TUN`은 Ethernet header가 없는 TUN device, `IFF_TAP`은 TAP device, `IFF_NO_PI`는 packet information header를 제공하지 않는다는 뜻입니다.

원하는 name이 있으면 `ifr.ifr_name`에 복사하고 `ioctl(fd, TUNSETIFF, &ifr)`로 interface를 등록합니다. 실패하면 file descriptor를 닫고 error를 반환하며, 성공하면 kernel이 정한 실제 name을 caller buffer로 복사하고 file descriptor를 반환합니다.

TUNSETIFF 주요 flag
Flag의미
IFF_TUNEthernet header 없는 TUN device
IFF_TAPEthernet frame을 사용하는 TAP device
IFF_NO_PI4-byte packet information header를 생략

Interface type과 userspace frame prefix를 결정합니다.

3. Program interface
====================

3.1 Network device allocation
-----------------------------

``char *dev`` should be the name of the device with a format string (e.g.
"tun%d"), but (as far as I can see) this can be any valid network device name.
Note that the character pointer becomes overwritten with the real device name
(e.g. "tun0")::

  #include <linux/if.h>
  #include <linux/if_tun.h>

  int tun_alloc(char *dev)
  {
      struct ifreq ifr;
      int fd, err;

      if( (fd = open("/dev/net/tun", O_RDWR)) < 0 )
         return tun_alloc_old(dev);

      memset(&ifr, 0, sizeof(ifr));

      /* Flags: IFF_TUN   - TUN device (no Ethernet headers)
       *        IFF_TAP   - TAP device
       *
       *        IFF_NO_PI - Do not provide packet information
       */
      ifr.ifr_flags = IFF_TUN;
      if( *dev )
         strscpy_pad(ifr.ifr_name, dev, IFNAMSIZ);

      if( (err = ioctl(fd, TUNSETIFF, (void *) &ifr)) < 0 ){
         close(fd);
         return err;
      }
      strcpy(dev, ifr.ifr_name);
      return fd;
  }

Packet information frame format

120-128

`IFF_NO_PI`를 설정하지 않으면 각 frame 앞에는 2-byte `Flags`, 2-byte `Proto`, 그리고 raw protocol frame(IP, IPv6 등)이 순서대로 옵니다.

TUN/TAP frame prefix
순서Field크기·내용
1Flags2 bytes
2Proto2 bytes
3Raw protocol frameIP, IPv6 또는 해당 L3/L2 frame

`IFF_NO_PI`가 없을 때 raw frame 앞에 붙는 4-byte metadata입니다.

3.2 Frame format
----------------

If flag IFF_NO_PI is not set each frame format is::

     Flags [2 bytes]
     Proto [2 bytes]
     Raw protocol(IP, IPv6, etc) frame.

Multiqueue interface와 queue 제어

129-208

Linux 3.8부터 multiqueue TUN/TAP을 지원합니다. 여러 file descriptor, 즉 여러 queue를 사용해 packet 송수신을 병렬화합니다. Device 할당 절차는 같지만 여러 queue를 만들려면 같은 device name과 `IFF_MULTI_QUEUE` flag로 `TUNSETIFF`를 여러 번 호출합니다.

`char *dev`는 device name, `queues`는 만들 queue 수, `fds`는 생성한 queue file descriptor를 caller에게 돌려줄 array입니다. 각 file descriptor가 userspace에서 접근할 수 있는 queue interface 역할을 합니다.

예제 `tun_alloc_mq()`는 `IFF_TAP | IFF_NO_PI | IFF_MULTI_QUEUE`를 지정하고 queue 수만큼 `/dev/net/tun`을 엽니다. 매 descriptor에 같은 `ifr`로 `TUNSETIFF`를 호출해 같은 multiqueue device에 queue를 붙이고 `fds[i]`에 저장합니다. 중간 실패 시 이미 만든 descriptor를 역순으로 닫고 error를 반환합니다.

새 `TUNSETQUEUE` ioctl은 queue를 enable하거나 disable합니다. `IFF_DETACH_QUEUE`는 queue를 비활성화하고 `IFF_ATTACH_QUEUE`는 활성화합니다. `TUNSETIFF`로 만든 직후 queue는 기본적으로 활성 상태입니다.

`tun_set_queue()` 예제는 대상 queue의 file descriptor와 boolean `enable`을 받아 `ifr_flags`에 attach 또는 detach flag를 넣고 `ioctl(fd, TUNSETQUEUE, &ifr)`를 호출합니다.

Multiqueue TUN/TAP 생성
dev name + IFF_MULTI_QUEUEopen /dev/net/tunTUNSETIFFfds[0] queue
같은 dev name반복 open/TUNSETIFFfds[n] queueparallel RX/TX
TUNSETQUEUEIFF_ATTACH_QUEUE 또는 IFF_DETACH_QUEUEqueue 상태 변경

같은 interface name에 여러 queue descriptor를 연결합니다.

3.3 Multiqueue tuntap interface
-------------------------------

From version 3.8, Linux supports multiqueue tuntap which can uses multiple
file descriptors (queues) to parallelize packets sending or receiving. The
device allocation is the same as before, and if user wants to create multiple
queues, TUNSETIFF with the same device name must be called many times with
IFF_MULTI_QUEUE flag.

``char *dev`` should be the name of the device, queues is the number of queues
to be created, fds is used to store and return the file descriptors (queues)
created to the caller. Each file descriptor were served as the interface of a
queue which could be accessed by userspace.

::

  #include <linux/if.h>
  #include <linux/if_tun.h>

  int tun_alloc_mq(char *dev, int queues, int *fds)
  {
      struct ifreq ifr;
      int fd, err, i;

      if (!dev)
          return -1;

      memset(&ifr, 0, sizeof(ifr));
      /* Flags: IFF_TUN   - TUN device (no Ethernet headers)
       *        IFF_TAP   - TAP device
       *
       *        IFF_NO_PI - Do not provide packet information
       *        IFF_MULTI_QUEUE - Create a queue of multiqueue device
       */
      ifr.ifr_flags = IFF_TAP | IFF_NO_PI | IFF_MULTI_QUEUE;
      strcpy(ifr.ifr_name, dev);

      for (i = 0; i < queues; i++) {
          if ((fd = open("/dev/net/tun", O_RDWR)) < 0)
             goto err;
          err = ioctl(fd, TUNSETIFF, (void *)&ifr);
          if (err) {
             close(fd);
             goto err;
          }
          fds[i] = fd;
      }

      return 0;
  err:
      for (--i; i >= 0; i--)
          close(fds[i]);
      return err;
  }

A new ioctl(TUNSETQUEUE) were introduced to enable or disable a queue. When
calling it with IFF_DETACH_QUEUE flag, the queue were disabled. And when
calling it with IFF_ATTACH_QUEUE flag, the queue were enabled. The queue were
enabled by default after it was created through TUNSETIFF.

fd is the file descriptor (queue) that we want to enable or disable, when
enable is true we enable it, otherwise we disable it::

  #include <linux/if.h>
  #include <linux/if_tun.h>

  int tun_set_queue(int fd, int enable)
  {
      struct ifreq ifr;

      memset(&ifr, 0, sizeof(ifr));

      if (enable)
         ifr.ifr_flags = IFF_ATTACH_QUEUE;
      else
         ifr.ifr_flags = IFF_DETACH_QUEUE;

      return ioctl(fd, TUNSETQUEUE, (void *)&ifr);
  }

FAQ: 지원 platform과 실제 동작

209-242

문서 작성 당시 TUN/TAP driver는 Linux kernel 2.2.x·2.4.x, FreeBSD 3.x·4.x·5.x, Solaris 2.6·7.0·8.0의 세 Unix 계열용으로 작성되어 있었습니다.

주요 용도는 tunneling이며 VTun이 이를 사용합니다. 또 다른 예인 `pipsecd`는 완전한 kernel routing을 사용할 수 있는 userspace IPsec 구현입니다.

Virtual network device는 physical media 대신 userspace program과 packet을 주고받는 Point-to-Point 또는 Ethernet device로 볼 수 있습니다.

예를 들어 `tap0`에 IPv6를 구성하면 kernel이 `tap0`으로 보내는 IPv6 packet이 VTun 같은 application에 전달됩니다. Application은 이를 encrypt·compress해 TCP나 UDP로 반대편에 보내고, 반대편 application은 decompress·decrypt한 뒤 TAP device에 씁니다. 그쪽 kernel은 이 packet을 실제 physical device에서 들어온 것처럼 처리합니다.

TAP 기반 tunnel
Kernel A IPv6tap0App encrypt/compressTCP/UDP tunnelApp decrypt/decompressTAP BKernel B

양쪽 userspace program이 virtual interface와 transport 사이를 이어 줍니다.

Universal TUN/TAP device driver Frequently Asked Question
=========================================================

1. What platforms are supported by TUN/TAP driver ?

Currently driver has been written for 3 Unices:

  - Linux kernels 2.2.x, 2.4.x
  - FreeBSD 3.x, 4.x, 5.x
  - Solaris 2.6, 7.0, 8.0

2. What is TUN/TAP driver used for?

As mentioned above, main purpose of TUN/TAP driver is tunneling.
It is used by VTun (http://vtun.sourceforge.net).

Another interesting application using TUN/TAP is pipsecd
(http://perso.enst.fr/~beyssac/pipsec/), a userspace IPSec
implementation that can use complete kernel routing (unlike FreeS/WAN).

3. How does Virtual network device actually work ?

Virtual network device can be viewed as a simple Point-to-Point or
Ethernet device, which instead of receiving packets from a physical
media, receives them from user space program and instead of sending
packets via physical media sends them to the user space program.

Let's say that you configured IPv6 on the tap0, then whenever
the kernel sends an IPv6 packet to tap0, it is passed to the application
(VTun for example). The application encrypts, compresses and sends it to
the other side over TCP or UDP. The application on the other side decompresses
and decrypts the data received and writes the packet to the TAP device,
the kernel handles the packet like it came from real physical device.

FAQ: TUN·TAP·BPF·bridge 차이

243-259

TUN은 IP frame을 다루고 TAP은 Ethernet frame을 다룹니다. 따라서 TUN 사용 시 IP packet을, TAP 사용 시 Ethernet frame을 읽고 써야 합니다.

BPF는 기존 network interface에 붙일 수 있는 고급 packet filter이며 virtual network interface 자체를 제공하지 않습니다. TUN/TAP driver는 virtual network interface를 제공하고, 그 interface에 BPF를 붙일 수도 있습니다.

TAP driver는 kernel Ethernet bridging을 지원합니다. 문서가 언급한 Linux와 FreeBSD driver 모두 Ethernet bridge에 사용할 수 있습니다.

4. What is the difference between TUN driver and TAP driver?

TUN works with IP frames. TAP works with Ethernet frames.

This means that you have to read/write IP packets when you are using tun and
ethernet frames when using tap.

5. What is the difference between BPF and TUN/TAP driver?

BPF is an advanced packet filter. It can be attached to existing
network interface. It does not provide a virtual network interface.
A TUN/TAP driver does provide a virtual network interface and it is possible
to attach BPF to this interface.

6. Does TAP driver support kernel Ethernet bridging?

Yes. Linux and FreeBSD drivers support Ethernet bridging.