// SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause)
/* Copyright (C) 2019 Netronome Systems, Inc. */
/* Copyright (C) 2020 Facebook, Inc. */
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/mman.h>
#include <alloca.h>
#include <bpf/bpf.h>
#include <bpf/libbpf.h>
#include "disasm.h"
#include "test_progs.h"
#include "testing_helpers.h"
#include <linux/membarrier.h>
#include <linux/userfaultfd.h>

int parse_num_list(const char *s, bool **num_set, int *num_set_len)
{
	int i, set_len = 0, new_len, num, start = 0, end = -1;
	bool *set = NULL, *tmp, parsing_end = false;
	char *next;

	while (s[0]) {
		errno = 0;
		num = strtol(s, &next, 10);
		if (errno)
			return -errno;

		if (parsing_end)
			end = num;
		else
			start = num;

		if (!parsing_end && *next == '-') {
			s = next + 1;
			parsing_end = true;
			continue;
		} else if (*next == ',') {
			parsing_end = false;
			s = next + 1;
			end = num;
		} else if (*next == '\0') {
			parsing_end = false;
			s = next;
			end = num;
		} else {
			return -EINVAL;
		}

		if (start > end)
			return -EINVAL;

		if (end + 1 > set_len) {
			new_len = end + 1;
			tmp = realloc(set, new_len);
			if (!tmp) {
				free(set);
				return -ENOMEM;
			}
			for (i = set_len; i < start; i++)
				tmp[i] = false;
			set = tmp;
			set_len = new_len;
		}
		for (i = start; i <= end; i++)
			set[i] = true;
	}

	if (!set || parsing_end)
		return -EINVAL;

	*num_set = set;
	*num_set_len = set_len;

	return 0;
}

static int do_insert_test(struct test_filter_set *set,
			  char *test_str,
			  char *subtest_str)
{
	struct test_filter *tmp, *test;
	char **ctmp;
	int i;

	for (i = 0; i < set->cnt; i++) {
		test = &set->tests[i];

		if (strcmp(test_str, test->name) == 0) {
			free(test_str);
			goto subtest;
		}
	}

	tmp = realloc(set->tests, sizeof(*test) * (set->cnt + 1));
	if (!tmp)
		return -ENOMEM;

	set->tests = tmp;
	test = &set->tests[set->cnt];

	test->name = test_str;
	test->subtests = NULL;
	test->subtest_cnt = 0;

	set->cnt++;

subtest:
	if (!subtest_str)
		return 0;

	for (i = 0; i < test->subtest_cnt; i++) {
		if (strcmp(subtest_str, test->subtests[i]) == 0) {
			free(subtest_str);
			return 0;
		}
	}

	ctmp = realloc(test->subtests,
		       sizeof(*test->subtests) * (test->subtest_cnt + 1));
	if (!ctmp)
		return -ENOMEM;

	test->subtests = ctmp;
	test->subtests[test->subtest_cnt] = subtest_str;

	test->subtest_cnt++;

	return 0;
}

static int insert_test(struct test_filter_set *set,
		       char *test_spec,
		       bool is_glob_pattern)
{
	char *pattern, *subtest_str, *ext_test_str, *ext_subtest_str = NULL;
	int glob_chars = 0;

	if (is_glob_pattern) {
		pattern = "%s";
	} else {
		pattern = "*%s*";
		glob_chars = 2;
	}

	subtest_str = strchr(test_spec, '/');
	if (subtest_str) {
		*subtest_str = '\0';
		subtest_str += 1;
	}

	ext_test_str = malloc(strlen(test_spec) + glob_chars + 1);
	if (!ext_test_str)
		goto err;

	sprintf(ext_test_str, pattern, test_spec);

	if (subtest_str) {
		ext_subtest_str = malloc(strlen(subtest_str) + glob_chars + 1);
		if (!ext_subtest_str)
			goto err;

		sprintf(ext_subtest_str, pattern, subtest_str);
	}

	return do_insert_test(set, ext_test_str, ext_subtest_str);

err:
	free(ext_test_str);
	free(ext_subtest_str);

	return -ENOMEM;
}

int parse_test_list_file(const char *path,
			 struct test_filter_set *set,
			 bool is_glob_pattern)
{
	char *buf = NULL, *capture_start, *capture_end, *scan_end;
	size_t buflen = 0;
	int err = 0;
	FILE *f;

	f = fopen(path, "r");
	if (!f) {
		err = -errno;
		fprintf(stderr, "Failed to open '%s': %d\n", path, err);
		return err;
	}

	while (getline(&buf, &buflen, f) != -1) {
		capture_start = buf;

		while (isspace(*capture_start))
			++capture_start;

		capture_end = capture_start;
		scan_end = capture_start;

		while (*scan_end && *scan_end != '#') {
			if (!isspace(*scan_end))
				capture_end = scan_end;

			++scan_end;
		}

		if (capture_end == capture_start)
			continue;

		*(++capture_end) = '\0';

		err = insert_test(set, capture_start, is_glob_pattern);
		if (err)
			break;
	}

	free(buf);
	fclose(f);
	return err;
}

int parse_test_list(const char *s,
		    struct test_filter_set *set,
		    bool is_glob_pattern)
{
	char *input, *state = NULL, *test_spec;
	int err = 0, cnt = 0;

	input = strdup(s);
	if (!input)
		return -ENOMEM;

	while ((test_spec = strtok_r(cnt++ ? NULL : input, ",", &state))) {
		err = insert_test(set, test_spec, is_glob_pattern);
		if (err)
			break;
	}

	free(input);
	return err;
}

__u32 link_info_prog_id(const struct bpf_link *link, struct bpf_link_info *info)
{
	__u32 info_len = sizeof(*info);
	int err;

	memset(info, 0, sizeof(*info));
	err = bpf_link_get_info_by_fd(bpf_link__fd(link), info, &info_len);
	if (err) {
		printf("failed to get link info: %d\n", -errno);
		return 0;
	}
	return info->prog_id;
}

int extra_prog_load_log_flags = 0;

int testing_prog_flags(void)
{
	static int cached_flags = -1;
	static int prog_flags[] = { BPF_F_TEST_RND_HI32, BPF_F_TEST_REG_INVARIANTS };
	static struct bpf_insn insns[] = {
		BPF_MOV64_IMM(BPF_REG_0, 0),
		BPF_EXIT_INSN(),
	};
	int insn_cnt = ARRAY_SIZE(insns), i, fd, flags = 0;
	LIBBPF_OPTS(bpf_prog_load_opts, opts);

	if (cached_flags >= 0)
		return cached_flags;

	for (i = 0; i < ARRAY_SIZE(prog_flags); i++) {
		opts.prog_flags = prog_flags[i];
		fd = bpf_prog_load(BPF_PROG_TYPE_SOCKET_FILTER, "flag-test", "GPL",
				   insns, insn_cnt, &opts);
		if (fd >= 0) {
			flags |= prog_flags[i];
			close(fd);
		}
	}

	cached_flags = flags;
	return cached_flags;
}

int bpf_prog_test_load(const char *file, enum bpf_prog_type type,
		       struct bpf_object **pobj, int *prog_fd)
{
	LIBBPF_OPTS(bpf_object_open_opts, opts,
		.kernel_log_level = extra_prog_load_log_flags,
	);
	struct bpf_object *obj;
	struct bpf_program *prog;
	__u32 flags;
	int err;

	obj = bpf_object__open_file(file, &opts);
	if (!obj)
		return -errno;

	prog = bpf_object__next_program(obj, NULL);
	if (!prog) {
		err = -ENOENT;
		goto err_out;
	}

	if (type != BPF_PROG_TYPE_UNSPEC && bpf_program__type(prog) != type)
		bpf_program__set_type(prog, type);

	flags = bpf_program__flags(prog) | testing_prog_flags();
	bpf_program__set_flags(prog, flags);

	err = bpf_object__load(obj);
	if (err)
		goto err_out;

	*pobj = obj;
	*prog_fd = bpf_program__fd(prog);

	return 0;
err_out:
	bpf_object__close(obj);
	return err;
}

int bpf_test_load_program(enum bpf_prog_type type, const struct bpf_insn *insns,
			  size_t insns_cnt, const char *license,
			  __u32 kern_version, char *log_buf,
			  size_t log_buf_sz)
{
	LIBBPF_OPTS(bpf_prog_load_opts, opts,
		.kern_version = kern_version,
		.prog_flags = testing_prog_flags(),
		.log_level = extra_prog_load_log_flags,
		.log_buf = log_buf,
		.log_size = log_buf_sz,
	);

	return bpf_prog_load(type, NULL, license, insns, insns_cnt, &opts);
}

__u64 read_perf_max_sample_freq(void)
{
	__u64 sample_freq = 5000; /* fallback to 5000 on error */
	FILE *f;

	f = fopen("/proc/sys/kernel/perf_event_max_sample_rate", "r");
	if (f == NULL) {
		printf("Failed to open /proc/sys/kernel/perf_event_max_sample_rate: err %d\n"
		       "return default value: 5000\n", -errno);
		return sample_freq;
	}
	if (fscanf(f, "%llu", &sample_freq) != 1) {
		printf("Failed to parse /proc/sys/kernel/perf_event_max_sample_rate: err %d\n"
		       "return default value: 5000\n", -errno);
	}

	fclose(f);
	return sample_freq;
}

int finit_module(int fd, const char *param_values, int flags)
{
	return syscall(__NR_finit_module, fd, param_values, flags);
}

int delete_module(const char *name, int flags)
{
	return syscall(__NR_delete_module, name, flags);
}

int try_unload_module(const char *name, int retries, bool verbose)
{
	int ret, cnt = 0;

	if (kern_sync_rcu())
		fprintf(stdout, "Failed to trigger kernel-side RCU sync!\n");

	for (;;) {
		ret = delete_module(name, 0);
		if (!ret || errno != EAGAIN)
			break;
		if (++cnt > retries) {
			fprintf(stdout, "Unload of %s timed out\n", name);
			break;
		}
		usleep(100);
	}

	if (ret) {
		if (errno == ENOENT) {
			if (verbose)
				fprintf(stdout, "%s.ko is already unloaded.\n", name);
			return -1;
		}
		fprintf(stdout, "Failed to unload %s.ko from kernel: %d\n", name, -errno);
		return -1;
	}
	if (verbose)
		fprintf(stdout, "Successfully unloaded %s.ko.\n", name);
	return 0;
}

int unload_module(const char *name, bool verbose)
{
	return try_unload_module(name, 10000, verbose);
}

static int __load_module(const char *path, const char *param_values, bool verbose)
{
	int fd;

	if (verbose)
		fprintf(stdout, "Loading %s...\n", path);

	fd = open(path, O_RDONLY);
	if (fd < 0) {
		fprintf(stdout, "Can't find %s kernel module: %d\n", path, -errno);
		return -ENOENT;
	}
	if (finit_module(fd, param_values, 0)) {
		fprintf(stdout, "Failed to load %s into the kernel: %d\n", path, -errno);
		close(fd);
		return -EINVAL;
	}
	close(fd);

	if (verbose)
		fprintf(stdout, "Successfully loaded %s.\n", path);
	return 0;
}

int load_module_params(const char *path, const char *param_values, bool verbose)
{
	return __load_module(path, param_values, verbose);
}

int load_module(const char *path, bool verbose)
{
	return __load_module(path, "", verbose);
}

int unload_bpf_testmod(bool verbose)
{
	return unload_module("bpf_testmod", verbose);
}

int load_bpf_testmod(bool verbose)
{
	return load_module("bpf_testmod.ko", verbose);
}

/*
 * Trigger synchronize_rcu() in kernel.
 */
int kern_sync_rcu(void)
{
	return syscall(__NR_membarrier, MEMBARRIER_CMD_SHARED, 0, 0);
}

int uffd_block_page(void *fault_addr)
{
	struct uffdio_register uffd_register = {};
	struct uffdio_api uffd_api = {};
	int uffd;

	uffd = syscall(__NR_userfaultfd, O_CLOEXEC);
	if (uffd < 0)
		return -errno;

	uffd_api.api = UFFD_API;
	uffd_api.features = 0;
	if (ioctl(uffd, UFFDIO_API, &uffd_api)) {
		close(uffd);
		return -1;
	}

	uffd_register.range.start = (unsigned long)fault_addr;
	uffd_register.range.len = getpagesize();
	uffd_register.mode = UFFDIO_REGISTER_MODE_MISSING;
	if (ioctl(uffd, UFFDIO_REGISTER, &uffd_register)) {
		close(uffd);
		return -1;
	}
	return uffd;
}

int get_xlated_program(int fd_prog, struct bpf_insn **buf, __u32 *cnt)
{
	__u32 buf_element_size = sizeof(struct bpf_insn);
	struct bpf_prog_info info = {};
	__u32 info_len = sizeof(info);
	__u32 xlated_prog_len;

	if (bpf_prog_get_info_by_fd(fd_prog, &info, &info_len)) {
		perror("bpf_prog_get_info_by_fd failed");
		return -1;
	}

	xlated_prog_len = info.xlated_prog_len;
	if (xlated_prog_len % buf_element_size) {
		printf("Program length %u is not multiple of %u\n",
		       xlated_prog_len, buf_element_size);
		return -1;
	}

	*cnt = xlated_prog_len / buf_element_size;
	*buf = calloc(*cnt, buf_element_size);
	if (!*buf) {
		perror("can't allocate xlated program buffer");
		return -ENOMEM;
	}

	bzero(&info, sizeof(info));
	info.xlated_prog_len = xlated_prog_len;
	info.xlated_prog_insns = (__u64)(unsigned long)*buf;
	if (bpf_prog_get_info_by_fd(fd_prog, &info, &info_len)) {
		perror("second bpf_prog_get_info_by_fd failed");
		goto out_free_buf;
	}

	return 0;

out_free_buf:
	free(*buf);
	*buf = NULL;
	return -1;
}

bool is_jit_enabled(void)
{
	const char *jit_sysctl = "/proc/sys/net/core/bpf_jit_enable";
	bool enabled = false;
	int sysctl_fd;

	sysctl_fd = open(jit_sysctl, O_RDONLY);
	if (sysctl_fd != -1) {
		char tmpc;

		if (read(sysctl_fd, &tmpc, sizeof(tmpc)) == 1)
			enabled = (tmpc != '0');
		close(sysctl_fd);
	}

	return enabled;
}

int stack_mprotect(void)
{
	void *buf;
	long sz;
	int ret;

	sz = sysconf(_SC_PAGESIZE);
	if (sz < 0)
		return sz;

	buf = alloca(sz * 3);
	ret = mprotect((void *)(((unsigned long)(buf + sz)) & ~(sz - 1)), sz,
		       PROT_READ | PROT_WRITE | PROT_EXEC);
	return ret;
}
