Have you ever wondered what the Linux TUN/TAP driver is for? Wonder no more! After spending most of last weekend tweaking the NuttX Simulator network support, I now have a pretty good idea of what TUN/TAP is, what it’s useful for, and how it works.
Might as well pass it on, right?
What Is TUN/TAP?
The Linux TUN/TAP driver is primarily designed to support network
tunnels. In the Linux source,
has this to say:
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.
To put the matter more simply, the TUN/TAP driver creates a virtual network interface on your Linux box. This interface works just like any other; you can assign IP addresses, route to it, and so on. But when you send traffic to that interface, the traffic is routed to your program instead of to a real network. If your program sends traffic back, it’s handled by the interface just as though it came from a real network.
Each TUN/TAP device has two ends, which we’ll call the “far end” (which terminates on the Linux host), and the “near end” (which terminates at the file descriptor you use to talk to the device). Essentially, you’ve created a network interface on the Linux host, a network interface in your application, and a transmission medium that runs between the two.
But why on Earth would anyone other than developers of VPN software care about something like this?
The TUN/TAP driver is far more useful than one would expect. Use cases may include:
- VPN Tunnels - As previously discussed, you can use it in order to funnel network traffic through to another location.
- Protocol Development - If you’re developing a new network protocol, this can allow you to perfect it without writing a kernel-mode driver.
- Virtualization - Virtualization platforms like qemu can use it to provide “real” network interfaces for the virtual machines they host.
It’s the latter case that I’m most interested in, because this is also how RTOS platforms like Contiki or NuttX allow you to simulate networked devices under Linux.
But how do you use it?