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

#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 <net/ethernet.h>
#include <netinet/ip.h>
#include <netinet/ether.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 <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 TRANS_RAW "raw"
#define TRANS_RAW_LEN strlen(TRANS_RAW)

#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

/* 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;
	strncpy((char *)&ifr.ifr_name, iface, sizeof(ifr.ifr_name) - 1);

	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));
	strncpy((char *)&ifr.ifr_name, iface, sizeof(ifr.ifr_name) - 1);
	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;
	char *iface;
	struct vector_fds *result = 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 tap_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 tap_cleanup;
	}
	result->rx_fd = -1;
	result->tx_fd = -1;
	result->remote_addr = NULL;
	result->remote_addr_size = 0;

	/* TAP */

	fd = create_tap_fd(iface);
	if (fd < 0) {
		printk(UM_KERN_ERR "uml_tap: failed to create tun interface\n");
		goto tap_cleanup;
	}
	result->tx_fd = fd;
	result->rx_fd = fd;
	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;

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

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