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

#define _GNU_SOURCE
#include <sched.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <linux/compiler.h>

#include "test_progs.h"
#include "cgroup_helpers.h"
#include "network_helpers.h"
#include "test_tcp_hdr_options.h"
#include "test_tcp_hdr_options.skel.h"
#include "test_misc_tcp_hdr_options.skel.h"

#define LO_ADDR6 "::1"
#define CG_NAME "/tcpbpf-hdr-opt-test"

static struct bpf_test_option exp_passive_estab_in;
static struct bpf_test_option exp_active_estab_in;
static struct bpf_test_option exp_passive_fin_in;
static struct bpf_test_option exp_active_fin_in;
static struct hdr_stg exp_passive_hdr_stg;
static struct hdr_stg exp_active_hdr_stg = { .active = true, };

static struct test_misc_tcp_hdr_options *misc_skel;
static struct test_tcp_hdr_options *skel;
static int lport_linum_map_fd;
static int hdr_stg_map_fd;
static __u32 duration;
static int cg_fd;

struct sk_fds {
	int srv_fd;
	int passive_fd;
	int active_fd;
	int passive_lport;
	int active_lport;
};

static int create_netns(void)
{
	if (CHECK(unshare(CLONE_NEWNET), "create netns",
		  "unshare(CLONE_NEWNET): %s (%d)",
		  strerror(errno), errno))
		return -1;

	if (CHECK(system("ip link set dev lo up"), "run ip cmd",
		  "failed to bring lo link up\n"))
		return -1;

	return 0;
}

static int write_sysctl(const char *sysctl, const char *value)
{
	int fd, err, len;

	fd = open(sysctl, O_WRONLY);
	if (CHECK(fd == -1, "open sysctl", "open(%s): %s (%d)\n",
		  sysctl, strerror(errno), errno))
		return -1;

	len = strlen(value);
	err = write(fd, value, len);
	close(fd);
	if (CHECK(err != len, "write sysctl",
		  "write(%s, %s): err:%d %s (%d)\n",
		  sysctl, value, err, strerror(errno), errno))
		return -1;

	return 0;
}

static void print_hdr_stg(const struct hdr_stg *hdr_stg, const char *prefix)
{
	fprintf(stderr, "%s{active:%u, resend_syn:%u, syncookie:%u, fastopen:%u}\n",
		prefix ? : "", hdr_stg->active, hdr_stg->resend_syn,
		hdr_stg->syncookie, hdr_stg->fastopen);
}

static void print_option(const struct bpf_test_option *opt, const char *prefix)
{
	fprintf(stderr, "%s{flags:0x%x, max_delack_ms:%u, rand:0x%x}\n",
		prefix ? : "", opt->flags, opt->max_delack_ms, opt->rand);
}

static void sk_fds_close(struct sk_fds *sk_fds)
{
	close(sk_fds->srv_fd);
	close(sk_fds->passive_fd);
	close(sk_fds->active_fd);
}

static int sk_fds_shutdown(struct sk_fds *sk_fds)
{
	int ret, abyte;

	shutdown(sk_fds->active_fd, SHUT_WR);
	ret = read(sk_fds->passive_fd, &abyte, sizeof(abyte));
	if (CHECK(ret != 0, "read-after-shutdown(passive_fd):",
		  "ret:%d %s (%d)\n",
		  ret, strerror(errno), errno))
		return -1;

	shutdown(sk_fds->passive_fd, SHUT_WR);
	ret = read(sk_fds->active_fd, &abyte, sizeof(abyte));
	if (CHECK(ret != 0, "read-after-shutdown(active_fd):",
		  "ret:%d %s (%d)\n",
		  ret, strerror(errno), errno))
		return -1;

	return 0;
}

static int sk_fds_connect(struct sk_fds *sk_fds, bool fast_open)
{
	const char fast[] = "FAST!!!";
	struct sockaddr_in6 addr6;
	socklen_t len;

	sk_fds->srv_fd = start_server(AF_INET6, SOCK_STREAM, LO_ADDR6, 0, 0);
	if (CHECK(sk_fds->srv_fd == -1, "start_server", "%s (%d)\n",
		  strerror(errno), errno))
		goto error;

	if (fast_open)
		sk_fds->active_fd = fastopen_connect(sk_fds->srv_fd, fast,
						     sizeof(fast), 0);
	else
		sk_fds->active_fd = connect_to_fd(sk_fds->srv_fd, 0);

	if (CHECK_FAIL(sk_fds->active_fd == -1)) {
		close(sk_fds->srv_fd);
		goto error;
	}

	len = sizeof(addr6);
	if (CHECK(getsockname(sk_fds->srv_fd, (struct sockaddr *)&addr6,
			      &len), "getsockname(srv_fd)", "%s (%d)\n",
		  strerror(errno), errno))
		goto error_close;
	sk_fds->passive_lport = ntohs(addr6.sin6_port);

	len = sizeof(addr6);
	if (CHECK(getsockname(sk_fds->active_fd, (struct sockaddr *)&addr6,
			      &len), "getsockname(active_fd)", "%s (%d)\n",
		  strerror(errno), errno))
		goto error_close;
	sk_fds->active_lport = ntohs(addr6.sin6_port);

	sk_fds->passive_fd = accept(sk_fds->srv_fd, NULL, 0);
	if (CHECK(sk_fds->passive_fd == -1, "accept(srv_fd)", "%s (%d)\n",
		  strerror(errno), errno))
		goto error_close;

	if (fast_open) {
		char bytes_in[sizeof(fast)];
		int ret;

		ret = read(sk_fds->passive_fd, bytes_in, sizeof(bytes_in));
		if (CHECK(ret != sizeof(fast), "read fastopen syn data",
			  "expected=%lu actual=%d\n", sizeof(fast), ret)) {
			close(sk_fds->passive_fd);
			goto error_close;
		}
	}

	return 0;

error_close:
	close(sk_fds->active_fd);
	close(sk_fds->srv_fd);

error:
	memset(sk_fds, -1, sizeof(*sk_fds));
	return -1;
}

static int check_hdr_opt(const struct bpf_test_option *exp,
			 const struct bpf_test_option *act,
			 const char *hdr_desc)
{
	if (CHECK(memcmp(exp, act, sizeof(*exp)),
		  "expected-vs-actual", "unexpected %s\n", hdr_desc)) {
		print_option(exp, "expected: ");
		print_option(act, "  actual: ");
		return -1;
	}

	return 0;
}

static int check_hdr_stg(const struct hdr_stg *exp, int fd,
			 const char *stg_desc)
{
	struct hdr_stg act;

	if (CHECK(bpf_map_lookup_elem(hdr_stg_map_fd, &fd, &act),
		  "map_lookup(hdr_stg_map_fd)", "%s %s (%d)\n",
		  stg_desc, strerror(errno), errno))
		return -1;

	if (CHECK(memcmp(exp, &act, sizeof(*exp)),
		  "expected-vs-actual", "unexpected %s\n", stg_desc)) {
		print_hdr_stg(exp, "expected: ");
		print_hdr_stg(&act, "  actual: ");
		return -1;
	}

	return 0;
}

static int check_error_linum(const struct sk_fds *sk_fds)
{
	unsigned int nr_errors = 0;
	struct linum_err linum_err;
	int lport;

	lport = sk_fds->passive_lport;
	if (!bpf_map_lookup_elem(lport_linum_map_fd, &lport, &linum_err)) {
		fprintf(stderr,
			"bpf prog error out at lport:passive(%d), linum:%u err:%d\n",
			lport, linum_err.linum, linum_err.err);
		nr_errors++;
	}

	lport = sk_fds->active_lport;
	if (!bpf_map_lookup_elem(lport_linum_map_fd, &lport, &linum_err)) {
		fprintf(stderr,
			"bpf prog error out at lport:active(%d), linum:%u err:%d\n",
			lport, linum_err.linum, linum_err.err);
		nr_errors++;
	}

	return nr_errors;
}

static void check_hdr_and_close_fds(struct sk_fds *sk_fds)
{
	const __u32 expected_inherit_cb_flags =
		BPF_SOCK_OPS_PARSE_UNKNOWN_HDR_OPT_CB_FLAG |
		BPF_SOCK_OPS_WRITE_HDR_OPT_CB_FLAG |
		BPF_SOCK_OPS_STATE_CB_FLAG;

	if (sk_fds_shutdown(sk_fds))
		goto check_linum;

	if (CHECK(expected_inherit_cb_flags != skel->bss->inherit_cb_flags,
		  "Unexpected inherit_cb_flags", "0x%x != 0x%x\n",
		  skel->bss->inherit_cb_flags, expected_inherit_cb_flags))
		goto check_linum;

	if (check_hdr_stg(&exp_passive_hdr_stg, sk_fds->passive_fd,
			  "passive_hdr_stg"))
		goto check_linum;

	if (check_hdr_stg(&exp_active_hdr_stg, sk_fds->active_fd,
			  "active_hdr_stg"))
		goto check_linum;

	if (check_hdr_opt(&exp_passive_estab_in, &skel->bss->passive_estab_in,
			  "passive_estab_in"))
		goto check_linum;

	if (check_hdr_opt(&exp_active_estab_in, &skel->bss->active_estab_in,
			  "active_estab_in"))
		goto check_linum;

	if (check_hdr_opt(&exp_passive_fin_in, &skel->bss->passive_fin_in,
			  "passive_fin_in"))
		goto check_linum;

	check_hdr_opt(&exp_active_fin_in, &skel->bss->active_fin_in,
		      "active_fin_in");

check_linum:
	CHECK_FAIL(check_error_linum(sk_fds));
	sk_fds_close(sk_fds);
}

static void prepare_out(void)
{
	skel->bss->active_syn_out = exp_passive_estab_in;
	skel->bss->passive_synack_out = exp_active_estab_in;

	skel->bss->active_fin_out = exp_passive_fin_in;
	skel->bss->passive_fin_out = exp_active_fin_in;
}

static void reset_test(void)
{
	size_t optsize = sizeof(struct bpf_test_option);
	int lport, err;

	memset(&skel->bss->passive_synack_out, 0, optsize);
	memset(&skel->bss->passive_fin_out, 0, optsize);

	memset(&skel->bss->passive_estab_in, 0, optsize);
	memset(&skel->bss->passive_fin_in, 0, optsize);

	memset(&skel->bss->active_syn_out, 0, optsize);
	memset(&skel->bss->active_fin_out, 0, optsize);

	memset(&skel->bss->active_estab_in, 0, optsize);
	memset(&skel->bss->active_fin_in, 0, optsize);

	skel->bss->inherit_cb_flags = 0;

	skel->data->test_kind = TCPOPT_EXP;
	skel->data->test_magic = 0xeB9F;

	memset(&exp_passive_estab_in, 0, optsize);
	memset(&exp_active_estab_in, 0, optsize);
	memset(&exp_passive_fin_in, 0, optsize);
	memset(&exp_active_fin_in, 0, optsize);

	memset(&exp_passive_hdr_stg, 0, sizeof(exp_passive_hdr_stg));
	memset(&exp_active_hdr_stg, 0, sizeof(exp_active_hdr_stg));
	exp_active_hdr_stg.active = true;

	err = bpf_map_get_next_key(lport_linum_map_fd, NULL, &lport);
	while (!err) {
		bpf_map_delete_elem(lport_linum_map_fd, &lport);
		err = bpf_map_get_next_key(lport_linum_map_fd, &lport, &lport);
	}
}

static void fastopen_estab(void)
{
	struct bpf_link *link;
	struct sk_fds sk_fds;

	hdr_stg_map_fd = bpf_map__fd(skel->maps.hdr_stg_map);
	lport_linum_map_fd = bpf_map__fd(skel->maps.lport_linum_map);

	exp_passive_estab_in.flags = OPTION_F_RAND | OPTION_F_MAX_DELACK_MS;
	exp_passive_estab_in.rand = 0xfa;
	exp_passive_estab_in.max_delack_ms = 11;

	exp_active_estab_in.flags = OPTION_F_RAND | OPTION_F_MAX_DELACK_MS;
	exp_active_estab_in.rand = 0xce;
	exp_active_estab_in.max_delack_ms = 22;

	exp_passive_hdr_stg.fastopen = true;

	prepare_out();

	/* Allow fastopen without fastopen cookie */
	if (write_sysctl("/proc/sys/net/ipv4/tcp_fastopen", "1543"))
		return;

	link = bpf_program__attach_cgroup(skel->progs.estab, cg_fd);
	if (!ASSERT_OK_PTR(link, "attach_cgroup(estab)"))
		return;

	if (sk_fds_connect(&sk_fds, true)) {
		bpf_link__destroy(link);
		return;
	}

	check_hdr_and_close_fds(&sk_fds);
	bpf_link__destroy(link);
}

static void syncookie_estab(void)
{
	struct bpf_link *link;
	struct sk_fds sk_fds;

	hdr_stg_map_fd = bpf_map__fd(skel->maps.hdr_stg_map);
	lport_linum_map_fd = bpf_map__fd(skel->maps.lport_linum_map);

	exp_passive_estab_in.flags = OPTION_F_RAND | OPTION_F_MAX_DELACK_MS;
	exp_passive_estab_in.rand = 0xfa;
	exp_passive_estab_in.max_delack_ms = 11;

	exp_active_estab_in.flags = OPTION_F_RAND | OPTION_F_MAX_DELACK_MS |
					OPTION_F_RESEND;
	exp_active_estab_in.rand = 0xce;
	exp_active_estab_in.max_delack_ms = 22;

	exp_passive_hdr_stg.syncookie = true;
	exp_active_hdr_stg.resend_syn = true,

	prepare_out();

	/* Clear the RESEND to ensure the bpf prog can learn
	 * want_cookie and set the RESEND by itself.
	 */
	skel->bss->passive_synack_out.flags &= ~OPTION_F_RESEND;

	/* Enforce syncookie mode */
	if (write_sysctl("/proc/sys/net/ipv4/tcp_syncookies", "2"))
		return;

	link = bpf_program__attach_cgroup(skel->progs.estab, cg_fd);
	if (!ASSERT_OK_PTR(link, "attach_cgroup(estab)"))
		return;

	if (sk_fds_connect(&sk_fds, false)) {
		bpf_link__destroy(link);
		return;
	}

	check_hdr_and_close_fds(&sk_fds);
	bpf_link__destroy(link);
}

static void fin(void)
{
	struct bpf_link *link;
	struct sk_fds sk_fds;

	hdr_stg_map_fd = bpf_map__fd(skel->maps.hdr_stg_map);
	lport_linum_map_fd = bpf_map__fd(skel->maps.lport_linum_map);

	exp_passive_fin_in.flags = OPTION_F_RAND;
	exp_passive_fin_in.rand = 0xfa;

	exp_active_fin_in.flags = OPTION_F_RAND;
	exp_active_fin_in.rand = 0xce;

	prepare_out();

	if (write_sysctl("/proc/sys/net/ipv4/tcp_syncookies", "1"))
		return;

	link = bpf_program__attach_cgroup(skel->progs.estab, cg_fd);
	if (!ASSERT_OK_PTR(link, "attach_cgroup(estab)"))
		return;

	if (sk_fds_connect(&sk_fds, false)) {
		bpf_link__destroy(link);
		return;
	}

	check_hdr_and_close_fds(&sk_fds);
	bpf_link__destroy(link);
}

static void __simple_estab(bool exprm)
{
	struct bpf_link *link;
	struct sk_fds sk_fds;

	hdr_stg_map_fd = bpf_map__fd(skel->maps.hdr_stg_map);
	lport_linum_map_fd = bpf_map__fd(skel->maps.lport_linum_map);

	exp_passive_estab_in.flags = OPTION_F_RAND | OPTION_F_MAX_DELACK_MS;
	exp_passive_estab_in.rand = 0xfa;
	exp_passive_estab_in.max_delack_ms = 11;

	exp_active_estab_in.flags = OPTION_F_RAND | OPTION_F_MAX_DELACK_MS;
	exp_active_estab_in.rand = 0xce;
	exp_active_estab_in.max_delack_ms = 22;

	prepare_out();

	if (!exprm) {
		skel->data->test_kind = 0xB9;
		skel->data->test_magic = 0;
	}

	if (write_sysctl("/proc/sys/net/ipv4/tcp_syncookies", "1"))
		return;

	link = bpf_program__attach_cgroup(skel->progs.estab, cg_fd);
	if (!ASSERT_OK_PTR(link, "attach_cgroup(estab)"))
		return;

	if (sk_fds_connect(&sk_fds, false)) {
		bpf_link__destroy(link);
		return;
	}

	check_hdr_and_close_fds(&sk_fds);
	bpf_link__destroy(link);
}

static void no_exprm_estab(void)
{
	__simple_estab(false);
}

static void simple_estab(void)
{
	__simple_estab(true);
}

static void misc(void)
{
	const char send_msg[] = "MISC!!!";
	char recv_msg[sizeof(send_msg)];
	const unsigned int nr_data = 2;
	struct bpf_link *link;
	struct sk_fds sk_fds;
	int i, ret;

	lport_linum_map_fd = bpf_map__fd(misc_skel->maps.lport_linum_map);

	if (write_sysctl("/proc/sys/net/ipv4/tcp_syncookies", "1"))
		return;

	link = bpf_program__attach_cgroup(misc_skel->progs.misc_estab, cg_fd);
	if (!ASSERT_OK_PTR(link, "attach_cgroup(misc_estab)"))
		return;

	if (sk_fds_connect(&sk_fds, false)) {
		bpf_link__destroy(link);
		return;
	}

	for (i = 0; i < nr_data; i++) {
		/* MSG_EOR to ensure skb will not be combined */
		ret = send(sk_fds.active_fd, send_msg, sizeof(send_msg),
			   MSG_EOR);
		if (CHECK(ret != sizeof(send_msg), "send(msg)", "ret:%d\n",
			  ret))
			goto check_linum;

		ret = read(sk_fds.passive_fd, recv_msg, sizeof(recv_msg));
		if (CHECK(ret != sizeof(send_msg), "read(msg)", "ret:%d\n",
			  ret))
			goto check_linum;
	}

	if (sk_fds_shutdown(&sk_fds))
		goto check_linum;

	CHECK(misc_skel->bss->nr_syn != 1, "unexpected nr_syn",
	      "expected (1) != actual (%u)\n",
		misc_skel->bss->nr_syn);

	CHECK(misc_skel->bss->nr_data != nr_data, "unexpected nr_data",
	      "expected (%u) != actual (%u)\n",
	      nr_data, misc_skel->bss->nr_data);

	/* The last ACK may have been delayed, so it is either 1 or 2. */
	CHECK(misc_skel->bss->nr_pure_ack != 1 &&
	      misc_skel->bss->nr_pure_ack != 2,
	      "unexpected nr_pure_ack",
	      "expected (1 or 2) != actual (%u)\n",
		misc_skel->bss->nr_pure_ack);

	CHECK(misc_skel->bss->nr_fin != 1, "unexpected nr_fin",
	      "expected (1) != actual (%u)\n",
	      misc_skel->bss->nr_fin);

check_linum:
	CHECK_FAIL(check_error_linum(&sk_fds));
	sk_fds_close(&sk_fds);
	bpf_link__destroy(link);
}

struct test {
	const char *desc;
	void (*run)(void);
};

#define DEF_TEST(name) { #name, name }
static struct test tests[] = {
	DEF_TEST(simple_estab),
	DEF_TEST(no_exprm_estab),
	DEF_TEST(syncookie_estab),
	DEF_TEST(fastopen_estab),
	DEF_TEST(fin),
	DEF_TEST(misc),
};

void test_tcp_hdr_options(void)
{
	int i;

	skel = test_tcp_hdr_options__open_and_load();
	if (CHECK(!skel, "open and load skel", "failed"))
		return;

	misc_skel = test_misc_tcp_hdr_options__open_and_load();
	if (CHECK(!misc_skel, "open and load misc test skel", "failed"))
		goto skel_destroy;

	cg_fd = test__join_cgroup(CG_NAME);
	if (CHECK_FAIL(cg_fd < 0))
		goto skel_destroy;

	for (i = 0; i < ARRAY_SIZE(tests); i++) {
		if (!test__start_subtest(tests[i].desc))
			continue;

		if (create_netns())
			break;

		tests[i].run();

		reset_test();
	}

	close(cg_fd);
skel_destroy:
	test_misc_tcp_hdr_options__destroy(misc_skel);
	test_tcp_hdr_options__destroy(skel);
}
