tools/testing/selftests/net/tun.c

Source file repositories/reference/linux-study-clean/tools/testing/selftests/net/tun.c

File Facts

System
Linux kernel
Corpus path
tools/testing/selftests/net/tun.c
Extension
.c
Size
29588 bytes
Lines
989
Domain
Support Tooling And Documentation
Bucket
tools
Inferred role
Support Tooling And Documentation: implementation source
Status
source implementation candidate

Why This File Exists

Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.

Dependency Surface

Detected Declarations

Annotated Snippet

struct geneve_setup_config {
	int family;
	union {
		struct in_addr r4;
		struct in6_addr r6;
	} remote;
	__be32 vnid;
	__be16 vnport;
	unsigned char hwaddr[6];
	uint8_t csum;
};

static int tun_attach(int fd, char *dev)
{
	struct ifreq ifr;

	memset(&ifr, 0, sizeof(ifr));
	strcpy(ifr.ifr_name, dev);
	ifr.ifr_flags = IFF_ATTACH_QUEUE;

	return ioctl(fd, TUNSETQUEUE, (void *)&ifr);
}

static int tun_detach(int fd, char *dev)
{
	struct ifreq ifr;

	memset(&ifr, 0, sizeof(ifr));
	strcpy(ifr.ifr_name, dev);
	ifr.ifr_flags = IFF_DETACH_QUEUE;

	return ioctl(fd, TUNSETQUEUE, (void *)&ifr);
}

static int tun_alloc(char *dev)
{
	struct ifreq ifr;
	int fd, err;

	fd = open("/dev/net/tun", O_RDWR);
	if (fd < 0) {
		fprintf(stderr, "can't open tun: %s\n", strerror(errno));
		return fd;
	}

	memset(&ifr, 0, sizeof(ifr));
	strcpy(ifr.ifr_name, dev);
	ifr.ifr_flags = IFF_TAP | IFF_NAPI | IFF_MULTI_QUEUE;

	err = ioctl(fd, TUNSETIFF, (void *)&ifr);
	if (err < 0) {
		fprintf(stderr, "can't TUNSETIFF: %s\n", strerror(errno));
		close(fd);
		return err;
	}
	strcpy(dev, ifr.ifr_name);
	return fd;
}

static int tun_delete(char *dev)
{
	return ip_link_del(dev);
}

static int tun_open(char *dev, const int flags, const int hdrlen,
		    const int features, const unsigned char *mac_addr)
{
	struct ifreq ifr = { 0 };
	int fd, sk = -1;

	fd = open("/dev/net/tun", O_RDWR);
	if (fd < 0) {
		perror("open");
		return -1;
	}

	ifr.ifr_flags = flags;
	if (ioctl(fd, TUNSETIFF, (void *)&ifr) < 0) {
		perror("ioctl(TUNSETIFF)");
		goto err;
	}
	strcpy(dev, ifr.ifr_name);

	if (hdrlen > 0) {
		if (ioctl(fd, TUNSETVNETHDRSZ, &hdrlen) < 0) {
			perror("ioctl(TUNSETVNETHDRSZ)");
			goto err;
		}
	}

Annotation

Implementation Notes