I am trying to understand the difference between different types of (virtual) interfaces (e.g. TUN/TAP, veth etc.) and was studying some of these types within the context of containers.

Is it possible to send packets between a container (in its own network namespace) to the host's network namespace using only TUN/TAP interfaces or is a veth pair (one end in each namespace) required to do this?

From my understanding, TUN/TAP interfaces can only be used to send/receive packets to/from userspace from/to the network stack corresponding to the network namespace of that interface and not send packets between network namespaces. Is this correct?


A tun/tap interface always belongs to some application: Packets send to the interface get read by the application, and packets written by the application enter the kernel network stack through this interface.

Typically, you'll connect up network namespace with virtual ethernet pairs (veth). They just forward packets to the other interface of the pair.

Nothing stops you from writing an application that does exactly this: Open two tun/tap interfaces, read packets from one and forward it to the other, and vice versa. There are also ready-made applications you could use to do this, e.g. socat.

You can even write two applications, where each application opens a single tun/tap interface, and the applications communicate with each other using other means, and implement forwarding this way. Basically all VPN applications work this way (though for VPN applications "by other means" is typically "over an existing network connection", so it doesn't really count).

So yes, with the right application(s), you can connect namespaces with tun/tap interfaces. However, in general it doesn't make a lot of sense to do that, because you have to write such an application, and it will be less efficient than just using a veth-pair.


I tried moving one tun interface of socat into a network namespace ns0 I created, and it works fine as I had expected, despite socat running in the main network namespace:

socat TUN:,tun-name=tun0a,iff-up TUN:,tun-name=tun0b
ip link set tun0b netns ns0

and then you again have to set the address for tun0b after the move.

So the "crossover" happens by having one (or both) tun/tap network interface(s) in a different namespace than the process.

  • very useful info thanks, how does it work sending packets between network namespaces with tun/tap though - a thread in one network namespace sending data to a tun/tap interface in that network namespace is only going to ever end up in the network stack of that network namespace, where does the crossover into another network namespace happen? – dippynark Nov 16 '18 at 9:03
  • Good question. As one can move interfaces into other namespaces with ip netns ..., I just assumed this would also work for tun/tap interfaces no matter which network namespace the process is in, but maybe it doesn't. Simplest way would be to use socat and try it out, but I can't do that here right now. I'll try later if I have time. In the worst case, two child processes running in different namespaces and using whatever inter-process communication they like should do the trick. – dirkt Nov 16 '18 at 9:31
  • 1
    I thought the socket's file descriptor retained the network namespace in which it was created regardless of which network namespace the interface lives in. Wireguard for example suggests using this technique/feature to avoid routing table conflicts with the main network namespace. Jason explain it here: wireguard.com/netns – David Cowden Dec 7 '19 at 6:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.