tun / tapデバイスを作成するときに名前空間をどのように指定しますか?

tun / tapデバイスを作成するときに名前空間をどのように指定しますか?

Linuxでは、C言語を使用して新しい調整/タブデバイスを作成できます。たとえば、次のようになります。

int fd = open("/dev/net/tun", O_RDWR);
ioctl(fd, TUNSETIFF, (void *)&ifr);

これにより、現在のネットワーク名前空間に新しいネットワークインターフェイスが作成されます。その後、同様の方法でip link set tap0 netns fooシェルから別の名前空間に移動できます。

最初に正しい名前空間に作成するか、少なくとも私のCコードからその名前空間に移動する正しい方法は何ですか?

ベストアンサー1

tun作成したい場合既存のsetns()ネームスペースを使用するには、トンデバイスを作成する前に、システムコールを使用してプロセスのネットワークネームスペースを設定できる必要があります。たとえば、「blue」という名前空間があるとします。

# ip netns
blue

次のコードは、この名前空間で tun デバイスを開きます。

#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);
}

tun上記のコードが実行されると、デバイスが適切な名前空間に作成されていることを確認できます。

# 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 

おすすめ記事