Se você estiver tentando criar um dispositivo tun
em um namespace existente , poderá usar a chamada de sistema setns()
antes de criar o dispositivo tun para definir o namespace de rede de seu processo. Por exemplo, supondo que exista um namespace chamado "blue":
# ip netns
blue
O código a seguir abrirá um dispositivo tun nesse 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);
}
Enquanto o código acima está em execução, podemos verificar se o dispositivo tun
foi criado no namespace apropriado:
# 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