// SPDX-License-Identifier: GPL-2.0
#define _GNU_SOURCE
#include <pthread.h>
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <asm/types.h>
#include <sys/syscall.h>
#include <errno.h>
#include <string.h>
#include <linux/bpf.h>
#include <sys/socket.h>
#include <bpf/bpf.h>
#include <bpf/libbpf.h>
#include <sys/ioctl.h>
#include <linux/rtnetlink.h>
#include <linux/perf_event.h>

#include "cgroup_helpers.h"

#include "test_tcpnotify.h"
#include "testing_helpers.h"

#define SOCKET_BUFFER_SIZE (getpagesize() < 8192L ? getpagesize() : 8192L)

pthread_t tid;
static bool exit_thread;

int rx_callbacks;

static void dummyfn(void *ctx, int cpu, void *data, __u32 size)
{
	struct tcp_notifier *t = data;

	if (t->type != 0xde || t->subtype != 0xad ||
	    t->source != 0xbe || t->hash != 0xef)
		return;
	rx_callbacks++;
}

void tcp_notifier_poller(struct perf_buffer *pb)
{
	int err;

	while (!exit_thread) {
		err = perf_buffer__poll(pb, 100);
		if (err < 0 && err != -EINTR) {
			printf("failed perf_buffer__poll: %d\n", err);
			return;
		}
	}
}

static void *poller_thread(void *arg)
{
	struct perf_buffer *pb = arg;

	tcp_notifier_poller(pb);
	return arg;
}

int verify_result(const struct tcpnotify_globals *result)
{
	return (result->ncalls > 0 && result->ncalls == rx_callbacks ? 0 : 1);
}

int main(int argc, char **argv)
{
	const char *file = "test_tcpnotify_kern.bpf.o";
	struct bpf_map *perf_map, *global_map;
	struct tcpnotify_globals g = {0};
	struct perf_buffer *pb = NULL;
	const char *cg_path = "/foo";
	int prog_fd, rv, cg_fd = -1;
	int error = EXIT_FAILURE;
	struct bpf_object *obj;
	char test_script[80];
	__u32 key = 0;

	libbpf_set_strict_mode(LIBBPF_STRICT_ALL);

	cg_fd = cgroup_setup_and_join(cg_path);
	if (cg_fd < 0)
		goto err;

	if (bpf_prog_test_load(file, BPF_PROG_TYPE_SOCK_OPS, &obj, &prog_fd)) {
		printf("FAILED: load_bpf_file failed for: %s\n", file);
		goto err;
	}

	rv = bpf_prog_attach(prog_fd, cg_fd, BPF_CGROUP_SOCK_OPS, 0);
	if (rv) {
		printf("FAILED: bpf_prog_attach: %d (%s)\n",
		       error, strerror(errno));
		goto err;
	}

	perf_map = bpf_object__find_map_by_name(obj, "perf_event_map");
	if (!perf_map) {
		printf("FAIL:map '%s' not found\n", "perf_event_map");
		goto err;
	}

	global_map = bpf_object__find_map_by_name(obj, "global_map");
	if (!global_map) {
		printf("FAIL:map '%s' not found\n", "global_map");
		return -1;
	}

	pb = perf_buffer__new(bpf_map__fd(perf_map), 8, dummyfn, NULL, NULL, NULL);
	if (!pb)
		goto err;

	pthread_create(&tid, NULL, poller_thread, pb);

	sprintf(test_script,
		"iptables -A INPUT -p tcp --dport %d -j DROP",
		TESTPORT);
	if (system(test_script)) {
		printf("FAILED: execute command: %s, err %d\n", test_script, -errno);
		goto err;
	}

	sprintf(test_script,
		"nc 127.0.0.1 %d < /etc/passwd > /dev/null 2>&1 ",
		TESTPORT);
	if (system(test_script))
		printf("execute command: %s, err %d\n", test_script, -errno);

	sprintf(test_script,
		"iptables -D INPUT -p tcp --dport %d -j DROP",
		TESTPORT);
	if (system(test_script)) {
		printf("FAILED: execute command: %s, err %d\n", test_script, -errno);
		goto err;
	}

	rv = bpf_map_lookup_elem(bpf_map__fd(global_map), &key, &g);
	if (rv != 0) {
		printf("FAILED: bpf_map_lookup_elem returns %d\n", rv);
		goto err;
	}

	sleep(10);

	exit_thread = true;
	int ret = pthread_join(tid, NULL);
	if (ret) {
		printf("FAILED: pthread_join\n");
		goto err;
	}

	if (verify_result(&g)) {
		printf("FAILED: Wrong stats Expected %d calls, got %d\n",
			g.ncalls, rx_callbacks);
		goto err;
	}

	printf("PASSED!\n");
	error = 0;
err:
	bpf_prog_detach(cg_fd, BPF_CGROUP_SOCK_OPS);
	close(cg_fd);
	cleanup_cgroup_environment();
	perf_buffer__free(pb);
	return error;
}
