I'm trying to implement a simple VPN as a learning experience, and I came across a problem. After I create a TAP device, I cannot bring it up. Here is a shorter version of my code:
typedef struct {
int device;
struct ifreq& ifr;
} AllocatedTap;
static AllocatedTap tap;
static struct ifreq ifr;
int fd, err;
char dev[16] = "\0"; // Let the kernel pick a name
if ((fd = open(TUN_CLONE_DEVICE, O_RDWR)) < 0) {
return NULL;
}
memset(&ifr, 0, sizeof(ifr));
ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
if (*dev) {
strncpy(ifr.ifr_name, dev, IFNAMSIZ);
}
if ((err = ioctl(fd, TUNSETIFF, (void *) &ifr)) < 0) {
close(fd);
eturn NULL;
}
strcpy(dev, ifr.ifr_name);
tap.device = fd;
tap.ifr = 𝔦
return &tap;
After that, I bring it up with:
int fd, err;
fd = socket(AF_INET, SOCK_DGRAM, 0); // 0: automically chose protocol
if (fd < 0) {
return -1;
}
tap->ifr->ifr_flags |= IFF_UP;
if ((err = ioctl(fd, SIOCSIFFLAGS, &tap->ifr)) == -1) {
return err;
}
This will always result in a No Such Device
error when bringing the interface up. I can get it to work about half the time if I recreate the ifr
struct while only carrying over the ip_name
and ip_addr
fields.
I expect for the code to bring the interface up to not err, and to actually bring said interface up.
I have tried, as stated above, recrating the ifr
struct, which makes the code not error. However, using ip a
, I've found out that the interface isn't up.
Can anyone help me figure out what going on?
First, i write same code as yours, and i met the same problem. You shoule add ioctl(fd, TUNSETPERSIST, 0x1), then reopen the tun dev fd like this, and use TUNSETIFF again.