// 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 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, sizeof(ifr.ifr_name));

	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, sizeof(ifr.ifr_name));
	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;
}

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