// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
 */

#include <stdbool.h>
#include <stdio.h>
#include <unistd.h>
#include <stdarg.h>
#include <errno.h>
#include <stddef.h>
#include <string.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <linux/if_tun.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <netinet/ip.h>
#include <linux/if_ether.h>
#include <linux/if_packet.h>
#include <sys/wait.h>
#include <sys/uio.h>
#include <linux/virtio_net.h>
#include <netdb.h>
#include <stdlib.h>
#include <os.h>
#include <limits.h>
#include <um_malloc.h>
#include "vector_user.h"

#define ID_GRE 0
#define ID_L2TPV3 1
#define ID_BESS 2
#define ID_MAX 2

#define TOKEN_IFNAME "ifname"
#define TOKEN_SCRIPT "ifup"

#define TRANS_RAW "raw"
#define TRANS_RAW_LEN strlen(TRANS_RAW)

#define TRANS_FD "fd"
#define TRANS_FD_LEN strlen(TRANS_FD)

#define TRANS_VDE "vde"
#define TRANS_VDE_LEN strlen(TRANS_VDE)

#define VNET_HDR_FAIL "could not enable vnet headers on fd %d"
#define TUN_GET_F_FAIL "tapraw: TUNGETFEATURES failed: %s"
#define L2TPV3_BIND_FAIL "l2tpv3_open : could not bind socket err=%i"
#define UNIX_BIND_FAIL "unix_open : could not bind socket err=%i"
#define BPF_ATTACH_FAIL "Failed to attach filter size %d prog %px to %d, err %d\n"
#define BPF_DETACH_FAIL "Failed to detach filter size %d prog %px to %d, err %d\n"

#define MAX_UN_LEN 107

static const char padchar[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
static const char *template = "tapXXXXXX";

/* This is very ugly and brute force lookup, but it is done
 * only once at initialization so not worth doing hashes or
 * anything more intelligent
 */

char *uml_vector_fetch_arg(struct arglist *ifspec, char *token)
{
	int i;

	for (i = 0; i < ifspec->numargs; i++) {
		if (strcmp(ifspec->tokens[i], token) == 0)
			return ifspec->values[i];
	}
	return NULL;

}

struct arglist *uml_parse_vector_ifspec(char *arg)
{
	struct arglist *result;
	int pos, len;
	bool parsing_token = true, next_starts = true;

	if (arg == NULL)
		return NULL;
	result = uml_kmalloc(sizeof(struct arglist), UM_GFP_KERNEL);
	if (result == NULL)
		return NULL;
	result->numargs = 0;
	len = strlen(arg);
	for (pos = 0; pos < len; pos++) {
		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);
	sock.sll_ifindex = ifr.ifr_ifindex;

	if (bind(fd,
		(struct sockaddr *) &sock, sizeof(struct sockaddr_ll)) < 0) {
		err = -errno;
		goto raw_fd_cleanup;
	}
	return fd;
raw_fd_cleanup:
	printk(UM_KERN_ERR "user_init_raw: init failed, error %d", err);
	if (fd >= 0)
		os_close_file(fd);
	return err;
}


static struct vector_fds *user_init_tap_fds(struct arglist *ifspec)
{
	int fd = -1, i;
	char *iface;
	struct vector_fds *result = NULL;
	bool dynamic = false;
	char dynamic_ifname[IFNAMSIZ];
	char *argv[] = {NULL, NULL, NULL, NULL};

	iface = uml_vector_fetch_arg(ifspec, TOKEN_IFNAME);
	if (iface == NULL) {
		dynamic = true;
		iface = dynamic_ifname;
		srand(getpid());
	}

	result = uml_kmalloc(sizeof(struct vector_fds), UM_GFP_KERNEL);
	if (result == NULL) {
		printk(UM_KERN_ERR "uml_tap: failed to allocate file descriptors\n");
		goto tap_cleanup;
	}
	result->rx_fd = -1;
	result->tx_fd = -1;
	result->remote_addr = NULL;
	result->remote_addr_size = 0;

	/* TAP */
	do {
		if (dynamic) {
			strcpy(iface, template);
			for (i = 0; i < strlen(iface); i++) {
				if (iface[i] == 'X') {
					iface[i] = padchar[rand() % strlen(padchar)];
				}
			}
		}
		fd = create_tap_fd(iface);
		if ((fd < 0) && (!dynamic)) {
			printk(UM_KERN_ERR "uml_tap: failed to create tun interface\n");
			goto tap_cleanup;
		}
		result->tx_fd = fd;
		result->rx_fd = fd;
	} while (fd < 0);

	argv[0] = uml_vector_fetch_arg(ifspec, TOKEN_SCRIPT);
	if (argv[0]) {
		argv[1] = iface;
		run_helper(NULL, NULL, argv);
	}

	return result;
tap_cleanup:
	printk(UM_KERN_ERR "user_init_tap: init failed, error %d", fd);
	kfree(result);
	return NULL;
}

static struct vector_fds *user_init_hybrid_fds(struct arglist *ifspec)
{
	char *iface;
	struct vector_fds *result = NULL;
	char *argv[] = {NULL, NULL, NULL, NULL};

	iface = uml_vector_fetch_arg(ifspec, TOKEN_IFNAME);
	if (iface == NULL) {
		printk(UM_KERN_ERR "uml_tap: failed to parse interface spec\n");
		goto hybrid_cleanup;
	}

	result = uml_kmalloc(sizeof(struct vector_fds), UM_GFP_KERNEL);
	if (result == NULL) {
		printk(UM_KERN_ERR "uml_tap: failed to allocate file descriptors\n");
		goto hybrid_cleanup;
	}
	result->rx_fd = -1;
	result->tx_fd = -1;
	result->remote_addr = NULL;
	result->remote_addr_size = 0;

	/* TAP */

	result->tx_fd = create_tap_fd(iface);
	if (result->tx_fd < 0) {
		printk(UM_KERN_ERR "uml_tap: failed to create tun interface: %i\n", result->tx_fd);
		goto hybrid_cleanup;
	}

	/* RAW */

	result->rx_fd = create_raw_fd(iface, ETH_P_ALL, ETH_P_ALL);
	if (result->rx_fd == -1) {
		printk(UM_KERN_ERR
			"uml_tap: failed to create paired raw socket: %i\n", result->rx_fd);
		goto hybrid_cleanup;
	}

	argv[0] = uml_vector_fetch_arg(ifspec, TOKEN_SCRIPT);
	if (argv[0]) {
		argv[1] = iface;
		run_helper(NULL, NULL, argv);
	}
	return result;
hybrid_cleanup:
	printk(UM_KERN_ERR "user_init_hybrid: init failed");
	kfree(result);
	return NULL;
}

static struct vector_fds *user_init_unix_fds(struct arglist *ifspec, int id)
{
	int fd = -1;
	int socktype;
	char *src, *dst;
	struct vector_fds *result = NULL;
	struct sockaddr_un *local_addr = NULL, *remote_addr = NULL;

	src = uml_vector_fetch_arg(ifspec, "src");
	dst = uml_vector_fetch_arg(ifspec, "dst");
	result = uml_kmalloc(sizeof(struct vector_fds), UM_GFP_KERNEL);
	if (result == NULL) {
		printk(UM_KERN_ERR "unix open:cannot allocate remote addr");
		goto unix_cleanup;
	}
	remote_addr = uml_kmalloc(sizeof(struct sockaddr_un), UM_GFP_KERNEL);
	if (remote_addr == NULL) {
		printk(UM_KERN_ERR "unix open:cannot allocate remote addr");
		goto unix_cleanup;
	}

	switch (id) {
	case ID_BESS:
		socktype = SOCK_SEQPACKET;
		if ((src != NULL) && (strlen(src) <= MAX_UN_LEN)) {
			local_addr = uml_kmalloc(sizeof(struct sockaddr_un), UM_GFP_KERNEL);
			if (local_addr == NULL) {
				printk(UM_KERN_ERR "bess open:cannot allocate local addr");
				goto unix_cleanup;
			}
			local_addr->sun_family = AF_UNIX;
			memcpy(local_addr->sun_path, src, strlen(src) + 1);
		}
		if ((dst == NULL) || (strlen(dst) > MAX_UN_LEN))
			goto unix_cleanup;
		remote_addr->sun_family = AF_UNIX;
		memcpy(remote_addr->sun_path, dst, strlen(dst) + 1);
		break;
	default:
		printk(KERN_ERR "Unsupported unix socket type\n");
		return NULL;
	}

	fd = socket(AF_UNIX, socktype, 0);
	if (fd == -1) {
		printk(UM_KERN_ERR
			"unix open: could not open socket, error = %d",
			-errno
		);
		goto unix_cleanup;
	}
	if (local_addr != NULL) {
		if (bind(fd, (struct sockaddr *) local_addr, sizeof(struct sockaddr_un))) {
			printk(UM_KERN_ERR UNIX_BIND_FAIL, errno);
			goto unix_cleanup;
		}
	}
	switch (id) {
	case ID_BESS:
		if (connect(fd, (const struct sockaddr *) remote_addr, sizeof(struct sockaddr_un)) < 0) {
			printk(UM_KERN_ERR "bess open:cannot connect to %s %i", remote_addr->sun_path, -errno);
			goto unix_cleanup;
		}
		break;
	}
	result->rx_fd = fd;
	result->tx_fd = fd;
	result->remote_addr_size = sizeof(struct sockaddr_un);
	result->remote_addr = remote_addr;
	return result;
unix_cleanup:
	if (fd >= 0)
		os_close_file(fd);
	kfree(remote_addr);
	kfree(result);
	return NULL;
}

static int strtofd(const char *nptr)
{
	long fd;
	char *endptr;

	if (nptr == NULL)
		return -1;

	errno = 0;
	fd = strtol(nptr, &endptr, 10);
	if (nptr == endptr ||
		errno != 0 ||
		*endptr != '\0' ||
		fd < 0 ||
		fd > INT_MAX) {
		return -1;
	}
	return fd;
}

static struct vector_fds *user_init_fd_fds(struct arglist *ifspec)
{
	int fd = -1;
	char *fdarg = NULL;
	struct vector_fds *result = NULL;

	fdarg = uml_vector_fetch_arg(ifspec, "fd");
	fd = strtofd(fdarg);
	if (fd == -1) {
		printk(UM_KERN_ERR "fd open: bad or missing fd argument");
		goto fd_cleanup;
	}

	result = uml_kmalloc(sizeof(struct vector_fds), UM_GFP_KERNEL);
	if (result == NULL) {
		printk(UM_KERN_ERR "fd open: allocation failed");
		goto fd_cleanup;
	}

	result->rx_fd = fd;
	result->tx_fd = fd;
	result->remote_addr_size = 0;
	result->remote_addr = NULL;
	return result;

fd_cleanup:
	if (fd >= 0)
		os_close_file(fd);
	kfree(result);
	return NULL;
}

/* enough char to store an int type */
#define ENOUGH(type) ((CHAR_BIT * sizeof(type) - 1) / 3 + 2)
#define ENOUGH_OCTAL(type) ((CHAR_BIT * sizeof(type) + 2) / 3)
/* vde_plug --descr xx --port2 xx --mod2 xx --group2 xx seqpacket://NN vnl (NULL) */
#define VDE_MAX_ARGC 12
#define VDE_SEQPACKET_HEAD "seqpacket://"
#define VDE_SEQPACKET_HEAD_LEN (sizeof(VDE_SEQPACKET_HEAD) - 1)
#define VDE_DEFAULT_DESCRIPTION "UML"

static struct vector_fds *user_init_vde_fds(struct arglist *ifspec)
{
	char seqpacketvnl[VDE_SEQPACKET_HEAD_LEN + ENOUGH(int) + 1];
	char *argv[VDE_MAX_ARGC] = {"vde_plug"};
	int argc = 1;
	int rv;
	int sv[2];
	struct vector_fds *result = NULL;

	char *vnl = uml_vector_fetch_arg(ifspec,"vnl");
	char *descr = uml_vector_fetch_arg(ifspec,"descr");
	char *port = uml_vector_fetch_arg(ifspec,"port");
	char *mode = uml_vector_fetch_arg(ifspec,"mode");
	char *group = uml_vector_fetch_arg(ifspec,"group");
	if (descr == NULL) descr = VDE_DEFAULT_DESCRIPTION;

	argv[argc++] = "--descr";
	argv[argc++] = descr;
	if (port != NULL) {
		argv[argc++] = "--port2";
		argv[argc++] = port;
	}
	if (mode != NULL) {
		argv[argc++] = "--mod2";
		argv[argc++] = mode;
	}
	if (group != NULL) {
		argv[argc++] = "--group2";
		argv[argc++] = group;
	}
	argv[argc++] = seqpacketvnl;
	argv[argc++] = vnl;
	argv[argc++] = NULL;

	rv = socketpair(AF_UNIX, SOCK_SEQPACKET, 0, sv);
	if (rv  < 0) {
		printk(UM_KERN_ERR "vde: seqpacket socketpair err %d", -errno);
		return NULL;
	}
	rv = os_set_exec_close(sv[0]);
	if (rv  < 0) {
		printk(UM_KERN_ERR "vde: seqpacket socketpair cloexec err %d", -errno);
		goto vde_cleanup_sv;
	}
	snprintf(seqpacketvnl, sizeof(seqpacketvnl), VDE_SEQPACKET_HEAD "%d", sv[1]);

	run_helper(NULL, NULL, argv);

	close(sv[1]);

	result = uml_kmalloc(sizeof(struct vector_fds), UM_GFP_KERNEL);
	if (result == NULL) {
		printk(UM_KERN_ERR "fd open: allocation failed");
		goto vde_cleanup;
	}

	result->rx_fd = sv[0];
	result->tx_fd = sv[0];
	result->remote_addr_size = 0;
	result->remote_addr = NULL;
	return result;

vde_cleanup_sv:
	close(sv[1]);
vde_cleanup:
	close(sv[0]);
	return NULL;
}

static struct vector_fds *user_init_raw_fds(struct arglist *ifspec)
{
	int rxfd = -1, txfd = -1;
	int err = -ENOMEM;
	char *iface;
	struct vector_fds *result = NULL;
	char *argv[] = {NULL, NULL, NULL, NULL};

	iface = uml_vector_fetch_arg(ifspec, TOKEN_IFNAME);
	if (iface == NULL)
		goto raw_cleanup;

	rxfd = create_raw_fd(iface, ETH_P_ALL, ETH_P_ALL);
	if (rxfd == -1) {
		err = -errno;
		goto raw_cleanup;
	}
	txfd = create_raw_fd(iface, 0, ETH_P_IP); /* Turn off RX on this fd */
	if (txfd == -1) {
		err = -errno;
		goto raw_cleanup;
	}
	result = uml_kmalloc(sizeof(struct vector_fds), UM_GFP_KERNEL);
	if (result != NULL) {
		result->rx_fd = rxfd;
		result->tx_fd = txfd;
		result->remote_addr = NULL;
		result->remote_addr_size = 0;
	}
	argv[0] = uml_vector_fetch_arg(ifspec, TOKEN_SCRIPT);
	if (argv[0]) {
		argv[1] = iface;
		run_helper(NULL, NULL, argv);
	}
	return result;
raw_cleanup:
	printk(UM_KERN_ERR "user_init_raw: init failed, error %d", err);
	kfree(result);
	return NULL;
}


bool uml_raw_enable_qdisc_bypass(int fd)
{
	int optval = 1;

	if (setsockopt(fd,
		SOL_PACKET, PACKET_QDISC_BYPASS,
		&optval, sizeof(optval)) != 0) {
		return false;
	}
	return true;
}

bool uml_raw_enable_vnet_headers(int fd)
{
	int optval = 1;

	if (setsockopt(fd,
		SOL_PACKET, PACKET_VNET_HDR,
		&optval, sizeof(optval)) != 0) {
		printk(UM_KERN_INFO VNET_HDR_FAIL, fd);
		return false;
	}
	return true;
}
bool uml_tap_enable_vnet_headers(int fd)
{
	unsigned int features;
	int len = sizeof(struct virtio_net_hdr);

	if (ioctl(fd, TUNGETFEATURES, &features) == -1) {
		printk(UM_KERN_INFO TUN_GET_F_FAIL, strerror(errno));
		return false;
	}
	if ((features & IFF_VNET_HDR) == 0) {
		printk(UM_KERN_INFO "tapraw: No VNET HEADER support");
		return false;
	}
	ioctl(fd, TUNSETVNETHDRSZ, &len);
	return true;
}

static struct vector_fds *user_init_socket_fds(struct arglist *ifspec, int id)
{
	int err = -ENOMEM;
	int fd = -1, gairet;
	struct addrinfo srchints;
	struct addrinfo dsthints;
	bool v6, udp;
	char *value;
	char *src, *dst, *srcport, *dstport;
	struct addrinfo *gairesult = NULL;
	struct vector_fds *result = NULL;


	value = uml_vector_fetch_arg(ifspec, "v6");
	v6 = false;
	udp = false;
	if (value != NULL) {
		if (strtol((const char *) value, NULL, 10) > 0)
			v6 = true;
	}

	value = uml_vector_fetch_arg(ifspec, "udp");
	if (value != NULL) {
		if (strtol((const char *) value, NULL, 10) > 0)
			udp = true;
	}
	src = uml_vector_fetch_arg(ifspec, "src");
	dst = uml_vector_fetch_arg(ifspec, "dst");
	srcport = uml_vector_fetch_arg(ifspec, "srcport");
	dstport = uml_vector_fetch_arg(ifspec, "dstport");

	memset(&dsthints, 0, sizeof(dsthints));

	if (v6)
		dsthints.ai_family = AF_INET6;
	else
		dsthints.ai_family = AF_INET;

	switch (id) {
	case ID_GRE:
		dsthints.ai_socktype = SOCK_RAW;
		dsthints.ai_protocol = IPPROTO_GRE;
		break;
	case ID_L2TPV3:
		if (udp) {
			dsthints.ai_socktype = SOCK_DGRAM;
			dsthints.ai_protocol = 0;
		} else {
			dsthints.ai_socktype = SOCK_RAW;
			dsthints.ai_protocol = IPPROTO_L2TP;
		}
		break;
	default:
		printk(KERN_ERR "Unsupported socket type\n");
		return NULL;
	}
	memcpy(&srchints, &dsthints, sizeof(struct addrinfo));

	gairet = getaddrinfo(src, srcport, &dsthints, &gairesult);
	if ((gairet != 0) || (gairesult == NULL)) {
		printk(UM_KERN_ERR
			"socket_open : could not resolve src, error = %s",
			gai_strerror(gairet)
		);
		return NULL;
	}
	fd = socket(gairesult->ai_family,
		gairesult->ai_socktype, gairesult->ai_protocol);
	if (fd == -1) {
		printk(UM_KERN_ERR
			"socket_open : could not open socket, error = %d",
			-errno
		);
		goto cleanup;
	}
	if (bind(fd,
		(struct sockaddr *) gairesult->ai_addr,
		gairesult->ai_addrlen)) {
		printk(UM_KERN_ERR L2TPV3_BIND_FAIL, errno);
		goto cleanup;
	}

	if (gairesult != NULL)
		freeaddrinfo(gairesult);

	gairesult = NULL;

	gairet = getaddrinfo(dst, dstport, &dsthints, &gairesult);
	if ((gairet != 0) || (gairesult == NULL)) {
		printk(UM_KERN_ERR
			"socket_open : could not resolve dst, error = %s",
			gai_strerror(gairet)
		);
		return NULL;
	}

	result = uml_kmalloc(sizeof(struct vector_fds), UM_GFP_KERNEL);
	if (result != NULL) {
		result->rx_fd = fd;
		result->tx_fd = fd;
		result->remote_addr = uml_kmalloc(
			gairesult->ai_addrlen, UM_GFP_KERNEL);
		if (result->remote_addr == NULL)
			goto cleanup;
		result->remote_addr_size = gairesult->ai_addrlen;
		memcpy(
			result->remote_addr,
			gairesult->ai_addr,
			gairesult->ai_addrlen
		);
	}
	freeaddrinfo(gairesult);
	return result;
cleanup:
	if (gairesult != NULL)
		freeaddrinfo(gairesult);
	printk(UM_KERN_ERR "user_init_socket: init failed, error %d", err);
	if (fd >= 0)
		os_close_file(fd);
	if (result != NULL) {
		kfree(result->remote_addr);
		kfree(result);
	}
	return NULL;
}

struct vector_fds *uml_vector_user_open(
	int unit,
	struct arglist *parsed
)
{
	char *transport;

	if (parsed == NULL) {
		printk(UM_KERN_ERR "no parsed config for unit %d\n", unit);
		return NULL;
	}
	transport = uml_vector_fetch_arg(parsed, "transport");
	if (transport == NULL) {
		printk(UM_KERN_ERR "missing transport for unit %d\n", unit);
		return NULL;
	}
	if (strncmp(transport, TRANS_RAW, TRANS_RAW_LEN) == 0)
		return user_init_raw_fds(parsed);
	if (strncmp(transport, TRANS_HYBRID, TRANS_HYBRID_LEN) == 0)
		return user_init_hybrid_fds(parsed);
	if (strncmp(transport, TRANS_TAP, TRANS_TAP_LEN) == 0)
		return user_init_tap_fds(parsed);
	if (strncmp(transport, TRANS_GRE, TRANS_GRE_LEN) == 0)
		return user_init_socket_fds(parsed, ID_GRE);
	if (strncmp(transport, TRANS_L2TPV3, TRANS_L2TPV3_LEN) == 0)
		return user_init_socket_fds(parsed, ID_L2TPV3);
	if (strncmp(transport, TRANS_BESS, TRANS_BESS_LEN) == 0)
		return user_init_unix_fds(parsed, ID_BESS);
	if (strncmp(transport, TRANS_FD, TRANS_FD_LEN) == 0)
		return user_init_fd_fds(parsed);
	if (strncmp(transport, TRANS_VDE, TRANS_VDE_LEN) == 0)
		return user_init_vde_fds(parsed);
	return NULL;
}


int uml_vector_sendmsg(int fd, void *hdr, int flags)
{
	int n;

	CATCH_EINTR(n = sendmsg(fd, (struct msghdr *) hdr,  flags));
	if ((n < 0) && (errno == EAGAIN))
		return 0;
	if (n >= 0)
		return n;
	else
		return -errno;
}

int uml_vector_recvmsg(int fd, void *hdr, int flags)
{
	int n;
	struct msghdr *msg = (struct msghdr *) hdr;

	CATCH_EINTR(n = readv(fd, msg->msg_iov, msg->msg_iovlen));
	if ((n < 0) && (errno == EAGAIN))
		return 0;
	if (n >= 0)
		return n;
	else
		return -errno;
}

int uml_vector_writev(int fd, void *hdr, int iovcount)
{
	int n;

	CATCH_EINTR(n = writev(fd, (struct iovec *) hdr,  iovcount));
	if ((n < 0) && ((errno == EAGAIN) || (errno == ENOBUFS)))
		return 0;
	if (n >= 0)
		return n;
	else
		return -errno;
}

int uml_vector_sendmmsg(
	int fd,
	void *msgvec,
	unsigned int vlen,
	unsigned int flags)
{
	int n;

	CATCH_EINTR(n = sendmmsg(fd, (struct mmsghdr *) msgvec, vlen, flags));
	if ((n < 0) && ((errno == EAGAIN) || (errno == ENOBUFS)))
		return 0;
	if (n >= 0)
		return n;
	else
		return -errno;
}

int uml_vector_recvmmsg(
	int fd,
	void *msgvec,
	unsigned int vlen,
	unsigned int flags)
{
	int n;

	CATCH_EINTR(
		n = recvmmsg(fd, (struct mmsghdr *) msgvec, vlen, flags, 0));
	if ((n < 0) && (errno == EAGAIN))
		return 0;
	if (n >= 0)
		return n;
	else
		return -errno;
}
int uml_vector_attach_bpf(int fd, void *bpf)
{
	struct sock_fprog *prog = bpf;

	int err = setsockopt(fd, SOL_SOCKET, SO_ATTACH_FILTER, bpf, sizeof(struct sock_fprog));

	if (err < 0)
		printk(KERN_ERR BPF_ATTACH_FAIL, prog->len, prog->filter, fd, -errno);
	return err;
}

int uml_vector_detach_bpf(int fd, void *bpf)
{
	struct sock_fprog *prog = bpf;

	int err = setsockopt(fd, SOL_SOCKET, SO_DETACH_FILTER, bpf, sizeof(struct sock_fprog));
	if (err < 0)
		printk(KERN_ERR BPF_DETACH_FAIL, prog->len, prog->filter, fd, -errno);
	return err;
}
void *uml_vector_default_bpf(const void *mac)
{
	struct sock_filter *bpf;
	uint32_t *mac1 = (uint32_t *)(mac + 2);
	uint16_t *mac2 = (uint16_t *) mac;
	struct sock_fprog *bpf_prog;

	bpf_prog = uml_kmalloc(sizeof(struct sock_fprog), UM_GFP_KERNEL);
	if (bpf_prog) {
		bpf_prog->len = DEFAULT_BPF_LEN;
		bpf_prog->filter = NULL;
	} else {
		return NULL;
	}
	bpf = uml_kmalloc(
		sizeof(struct sock_filter) * DEFAULT_BPF_LEN, UM_GFP_KERNEL);
	if (bpf) {
		bpf_prog->filter = bpf;
		/* ld	[8] */
		bpf[0] = (struct sock_filter){ 0x20, 0, 0, 0x00000008 };
		/* jeq	#0xMAC[2-6] jt 2 jf 5*/
		bpf[1] = (struct sock_filter){ 0x15, 0, 3, ntohl(*mac1)};
		/* ldh	[6] */
		bpf[2] = (struct sock_filter){ 0x28, 0, 0, 0x00000006 };
		/* jeq	#0xMAC[0-1] jt 4 jf 5 */
		bpf[3] = (struct sock_filter){ 0x15, 0, 1, ntohs(*mac2)};
		/* ret	#0 */
		bpf[4] = (struct sock_filter){ 0x6, 0, 0, 0x00000000 };
		/* ret	#0x40000 */
		bpf[5] = (struct sock_filter){ 0x6, 0, 0, 0x00040000 };
	} else {
		kfree(bpf_prog);
		bpf_prog = NULL;
	}
	return bpf_prog;
}

/* Note - this function requires a valid mac being passed as an arg */

void *uml_vector_user_bpf(char *filename)
{
	struct sock_filter *bpf;
	struct sock_fprog *bpf_prog;
	struct stat statbuf;
	int res, ffd = -1;

	if (filename == NULL)
		return NULL;

	if (stat(filename, &statbuf) < 0) {
		printk(KERN_ERR "Error %d reading bpf file", -errno);
		return false;
	}
	bpf_prog = uml_kmalloc(sizeof(struct sock_fprog), UM_GFP_KERNEL);
	if (bpf_prog == NULL) {
		printk(KERN_ERR "Failed to allocate bpf prog buffer");
		return NULL;
	}
	bpf_prog->len = statbuf.st_size / sizeof(struct sock_filter);
	bpf_prog->filter = NULL;
	ffd = os_open_file(filename, of_read(OPENFLAGS()), 0);
	if (ffd < 0) {
		printk(KERN_ERR "Error %d opening bpf file", -errno);
		goto bpf_failed;
	}
	bpf = uml_kmalloc(statbuf.st_size, UM_GFP_KERNEL);
	if (bpf == NULL) {
		printk(KERN_ERR "Failed to allocate bpf buffer");
		goto bpf_failed;
	}
	bpf_prog->filter = bpf;
	res = os_read_file(ffd, bpf, statbuf.st_size);
	if (res < statbuf.st_size) {
		printk(KERN_ERR "Failed to read bpf program %s, error %d", filename, res);
		kfree(bpf);
		goto bpf_failed;
	}
	os_close_file(ffd);
	return bpf_prog;
bpf_failed:
	if (ffd > 0)
		os_close_file(ffd);
	kfree(bpf_prog);
	return NULL;
}
