If you are trying to create a tun
device in an existing namespace, you should be able to use the setns()
system call before creating the tun device to set the network namespace of your process. For example, assuming that there exists a namespace named "blue":
# ip netns blue
The following code will open a tun device in that namespace:
#define _GNU_SOURCE #include <fcntl.h> #include <sched.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/ioctl.h> #include <sys/socket.h> #include <sys/stat.h> #include <sys/types.h> #include <unistd.h> #include <linux/if.h> #include <linux/if_tun.h> int main() { int nsfd; int tunfd; struct ifreq ifr; nsfd = open("/run/netns/blue", O_RDONLY); if (setns(nsfd, CLONE_NEWNET) == -1) { perror("setns"); exit(1); } memset(&ifr, 0, sizeof(ifr)); ifr.ifr_flags = IFF_TUN; tunfd = open("/dev/net/tun", O_RDWR); if (ioctl(tunfd, TUNSETIFF, (void *)&ifr) < 0) { perror("ioctl"); exit(1); } // this is just here to prevent the code from exiting, which sleep(300); }
While the above code is running, we can verify that the tun
device has been created in the appropriate namespace:
# ip netns exec blue ip addr 1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default qlen 1 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 3: tun0: <POINTOPOINT,MULTICAST,NOARP> mtu 1500 qdisc noop state DOWN group default qlen 500 link/none
system("ip link ...")
but that is really ugly.libnfnetlink
or the source code ofiproute2
.