arch/um/drivers/vector_user.c

Source file repositories/reference/linux-study-clean/arch/um/drivers/vector_user.c

File Facts

System
Linux kernel
Corpus path
arch/um/drivers/vector_user.c
Extension
.c
Size
22540 bytes
Lines
942
Domain
Architecture Layer
Bucket
arch/um
Inferred role
Architecture Layer: implementation source
Status
source implementation candidate

Why This File Exists

CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.

Dependency Surface

Detected Declarations

Annotated Snippet

if (next_starts) {
			if (parsing_token) {
				result->tokens[result->numargs] = arg + pos;
			} else {
				result->values[result->numargs] = arg + pos;
				result->numargs++;
			}
			next_starts = false;
		}
		if (*(arg + pos) == '=') {
			if (parsing_token)
				parsing_token = false;
			else
				goto cleanup;
			next_starts = true;
			(*(arg + pos)) = '\0';
		}
		if (*(arg + pos) == ',') {
			parsing_token = true;
			next_starts = true;
			(*(arg + pos)) = '\0';
		}
	}
	return result;
cleanup:
	printk(UM_KERN_ERR "vector_setup - Couldn't parse '%s'\n", arg);
	kfree(result);
	return NULL;
}

/*
 * Socket/FD configuration functions. These return an structure
 * of rx and tx descriptors to cover cases where these are not
 * the same (f.e. read via raw socket and write via tap).
 */

#define PATH_NET_TUN "/dev/net/tun"


static int create_tap_fd(char *iface)
{
	struct ifreq ifr;
	int fd = -1;
	int err = -ENOMEM, offload;

	fd = open(PATH_NET_TUN, O_RDWR);
	if (fd < 0) {
		printk(UM_KERN_ERR "uml_tap: failed to open tun device\n");
		goto tap_fd_cleanup;
	}
	memset(&ifr, 0, sizeof(ifr));
	ifr.ifr_flags = IFF_TAP | IFF_NO_PI | IFF_VNET_HDR;
	strscpy(ifr.ifr_name, iface);

	err = ioctl(fd, TUNSETIFF, (void *) &ifr);
	if (err != 0) {
		printk(UM_KERN_ERR "uml_tap: failed to select tap interface\n");
		goto tap_fd_cleanup;
	}

	offload = TUN_F_CSUM | TUN_F_TSO4 | TUN_F_TSO6;
	ioctl(fd, TUNSETOFFLOAD, offload);
	return fd;
tap_fd_cleanup:
	if (fd >= 0)
		os_close_file(fd);
	return err;
}

static int create_raw_fd(char *iface, int flags, int proto)
{
	struct ifreq ifr;
	int fd = -1;
	struct sockaddr_ll sock;
	int err = -ENOMEM;

	fd = socket(AF_PACKET, SOCK_RAW, flags);
	if (fd == -1) {
		err = -errno;
		goto raw_fd_cleanup;
	}
	memset(&ifr, 0, sizeof(ifr));
	strscpy(ifr.ifr_name, iface);
	if (ioctl(fd, SIOCGIFINDEX, (void *) &ifr) < 0) {
		err = -errno;
		goto raw_fd_cleanup;
	}

	sock.sll_family = AF_PACKET;
	sock.sll_protocol = htons(proto);

Annotation

Implementation Notes