// SPDX-License-Identifier: GPL-2.0
/* Copyright (c) 2020 Facebook */

#include <sys/types.h>
#include <bpf/bpf.h>
#include <bpf/libbpf.h>
#include "test_progs.h"
#include "network_helpers.h"
#include "test_sk_storage_trace_itself.skel.h"
#include "test_sk_storage_tracing.skel.h"

#define LO_ADDR6 "::1"
#define TEST_COMM "test_progs"

struct sk_stg {
	__u32 pid;
	__u32 last_notclose_state;
	char comm[16];
};

static struct test_sk_storage_tracing *skel;
static __u32 duration;
static pid_t my_pid;

static int check_sk_stg(int sk_fd, __u32 expected_state)
{
	struct sk_stg sk_stg;
	int err;

	err = bpf_map_lookup_elem(bpf_map__fd(skel->maps.sk_stg_map), &sk_fd,
				  &sk_stg);
	if (!ASSERT_OK(err, "map_lookup(sk_stg_map)"))
		return -1;

	if (!ASSERT_EQ(sk_stg.last_notclose_state, expected_state,
		       "last_notclose_state"))
		return -1;

	if (!ASSERT_EQ(sk_stg.pid, my_pid, "pid"))
		return -1;

	if (!ASSERT_STREQ(sk_stg.comm, skel->bss->task_comm, "task_comm"))
		return -1;

	return 0;
}

static void do_test(void)
{
	int listen_fd = -1, passive_fd = -1, active_fd = -1, value = 1, err;
	char abyte;

	listen_fd = start_server(AF_INET6, SOCK_STREAM, LO_ADDR6, 0, 0);
	if (CHECK(listen_fd == -1, "start_server",
		  "listen_fd:%d errno:%d\n", listen_fd, errno))
		return;

	active_fd = connect_to_fd(listen_fd, 0);
	if (CHECK(active_fd == -1, "connect_to_fd", "active_fd:%d errno:%d\n",
		  active_fd, errno))
		goto out;

	err = bpf_map_update_elem(bpf_map__fd(skel->maps.del_sk_stg_map),
				  &active_fd, &value, 0);
	if (!ASSERT_OK(err, "map_update(del_sk_stg_map)"))
		goto out;

	passive_fd = accept(listen_fd, NULL, 0);
	if (CHECK(passive_fd == -1, "accept", "passive_fd:%d errno:%d\n",
		  passive_fd, errno))
		goto out;

	shutdown(active_fd, SHUT_WR);
	err = read(passive_fd, &abyte, 1);
	if (!ASSERT_OK(err, "read(passive_fd)"))
		goto out;

	shutdown(passive_fd, SHUT_WR);
	err = read(active_fd, &abyte, 1);
	if (!ASSERT_OK(err, "read(active_fd)"))
		goto out;

	err = bpf_map_lookup_elem(bpf_map__fd(skel->maps.del_sk_stg_map),
				  &active_fd, &value);
	if (!ASSERT_ERR(err, "map_lookup(del_sk_stg_map)"))
		goto out;

	err = check_sk_stg(listen_fd, BPF_TCP_LISTEN);
	if (!ASSERT_OK(err, "listen_fd sk_stg"))
		goto out;

	err = check_sk_stg(active_fd, BPF_TCP_FIN_WAIT2);
	if (!ASSERT_OK(err, "active_fd sk_stg"))
		goto out;

	err = check_sk_stg(passive_fd, BPF_TCP_LAST_ACK);
	ASSERT_OK(err, "passive_fd sk_stg");

out:
	if (active_fd != -1)
		close(active_fd);
	if (passive_fd != -1)
		close(passive_fd);
	if (listen_fd != -1)
		close(listen_fd);
}

void serial_test_sk_storage_tracing(void)
{
	struct test_sk_storage_trace_itself *skel_itself;
	int err;

	my_pid = getpid();

	skel_itself = test_sk_storage_trace_itself__open_and_load();

	if (!ASSERT_NULL(skel_itself, "test_sk_storage_trace_itself")) {
		test_sk_storage_trace_itself__destroy(skel_itself);
		return;
	}

	skel = test_sk_storage_tracing__open_and_load();
	if (!ASSERT_OK_PTR(skel, "test_sk_storage_tracing"))
		return;

	err = test_sk_storage_tracing__attach(skel);
	if (!ASSERT_OK(err, "test_sk_storage_tracing__attach")) {
		test_sk_storage_tracing__destroy(skel);
		return;
	}

	do_test();

	test_sk_storage_tracing__destroy(skel);
}
