// SPDX-License-Identifier: GPL-2.0
#include <test_progs.h>
#include <network_helpers.h>
#include <linux/netfilter/nf_conntrack_common.h>
#include "test_bpf_nf.skel.h"
#include "test_bpf_nf_fail.skel.h"

#define CT_OPTS_ERROR_GUARD 0x12345678

static char log_buf[1024 * 1024];

struct {
	const char *prog_name;
	const char *err_msg;
} test_bpf_nf_fail_tests[] = {
	{ "alloc_release", "kernel function bpf_ct_release R1 expected pointer to STRUCT nf_conn but" },
	{ "insert_insert", "kernel function bpf_ct_insert_entry R1 expected pointer to STRUCT nf_conn___init but" },
	{ "lookup_insert", "kernel function bpf_ct_insert_entry R1 expected pointer to STRUCT nf_conn___init but" },
	{ "set_timeout_after_insert", "kernel function bpf_ct_set_timeout R1 expected pointer to STRUCT nf_conn___init but" },
	{ "set_status_after_insert", "kernel function bpf_ct_set_status R1 expected pointer to STRUCT nf_conn___init but" },
	{ "change_timeout_after_alloc", "kernel function bpf_ct_change_timeout R1 expected pointer to STRUCT nf_conn but" },
	{ "change_status_after_alloc", "kernel function bpf_ct_change_status R1 expected pointer to STRUCT nf_conn but" },
	{ "write_not_allowlisted_field", "no write support to nf_conn at off" },
	{ "lookup_null_bpf_tuple", "Possibly NULL pointer passed to trusted R2" },
	{ "lookup_null_bpf_opts", "Possibly NULL pointer passed to trusted R4" },
	{ "xdp_lookup_null_bpf_tuple", "Possibly NULL pointer passed to trusted R2" },
	{ "xdp_lookup_null_bpf_opts", "Possibly NULL pointer passed to trusted R4" },
};

enum {
	TEST_XDP,
	TEST_TC_BPF,
};

#define TIMEOUT_MS		3000
#define IPS_STATUS_MASK		(IPS_CONFIRMED | IPS_SEEN_REPLY | \
				 IPS_SRC_NAT_DONE | IPS_DST_NAT_DONE | \
				 IPS_SRC_NAT | IPS_DST_NAT)

static int connect_to_server(int srv_fd)
{
	int fd = -1;

	fd = socket(AF_INET, SOCK_STREAM, 0);
	if (!ASSERT_GE(fd, 0, "socket"))
		goto out;

	if (!ASSERT_EQ(connect_fd_to_fd(fd, srv_fd, TIMEOUT_MS), 0, "connect_fd_to_fd")) {
		close(fd);
		fd = -1;
	}
out:
	return fd;
}

static void test_bpf_nf_ct(int mode)
{
	const char *iptables = "iptables-legacy -t raw %s PREROUTING -j CONNMARK --set-mark 42/0";
	int srv_fd = -1, client_fd = -1, srv_client_fd = -1;
	struct sockaddr_in peer_addr = {};
	struct test_bpf_nf *skel;
	int prog_fd, err;
	socklen_t len;
	u16 srv_port;
	char cmd[128];
	LIBBPF_OPTS(bpf_test_run_opts, topts,
		.data_in = &pkt_v4,
		.data_size_in = sizeof(pkt_v4),
		.repeat = 1,
	);

	if (SYS_NOFAIL("iptables-legacy --version")) {
		fprintf(stdout, "Missing required iptables-legacy tool\n");
		test__skip();
		return;
	}

	skel = test_bpf_nf__open_and_load();
	if (!ASSERT_OK_PTR(skel, "test_bpf_nf__open_and_load"))
		return;

	/* Enable connection tracking */
	snprintf(cmd, sizeof(cmd), iptables, "-A");
	if (!ASSERT_OK(system(cmd), cmd))
		goto end;

	srv_fd = start_server(AF_INET, SOCK_STREAM, "127.0.0.1", 0, TIMEOUT_MS);
	if (!ASSERT_GE(srv_fd, 0, "start_server"))
		goto end;

	srv_port = get_socket_local_port(srv_fd);
	if (!ASSERT_GE(srv_port, 0, "get_sock_local_port"))
		goto end;

	client_fd = connect_to_server(srv_fd);
	if (!ASSERT_GE(client_fd, 0, "connect_to_server"))
		goto end;

	len = sizeof(peer_addr);
	srv_client_fd = accept(srv_fd, (struct sockaddr *)&peer_addr, &len);
	if (!ASSERT_GE(srv_client_fd, 0, "accept"))
		goto end;
	if (!ASSERT_EQ(len, sizeof(struct sockaddr_in), "sockaddr len"))
		goto end;

	skel->bss->saddr = peer_addr.sin_addr.s_addr;
	skel->bss->sport = peer_addr.sin_port;
	skel->bss->daddr = peer_addr.sin_addr.s_addr;
	skel->bss->dport = srv_port;

	if (mode == TEST_XDP)
		prog_fd = bpf_program__fd(skel->progs.nf_xdp_ct_test);
	else
		prog_fd = bpf_program__fd(skel->progs.nf_skb_ct_test);

	err = bpf_prog_test_run_opts(prog_fd, &topts);
	if (!ASSERT_OK(err, "bpf_prog_test_run"))
		goto end;

	ASSERT_EQ(skel->bss->test_einval_reserved, -EINVAL, "Test EINVAL for reserved not set to 0");
	ASSERT_EQ(skel->bss->test_einval_reserved_new, -EINVAL, "Test EINVAL for reserved in new struct not set to 0");
	ASSERT_EQ(skel->bss->test_einval_netns_id, -EINVAL, "Test EINVAL for netns_id < -1");
	ASSERT_EQ(skel->bss->test_einval_len_opts, -EINVAL, "Test EINVAL for len__opts != NF_BPF_CT_OPTS_SZ");
	ASSERT_EQ(skel->bss->test_einval_len_opts_small_lookup, CT_OPTS_ERROR_GUARD,
		  "Test no error write for lookup opts__sz before error field");
	ASSERT_EQ(skel->bss->test_einval_len_opts_small_alloc, CT_OPTS_ERROR_GUARD,
		  "Test no error write for alloc opts__sz before error field");
	ASSERT_EQ(skel->bss->test_eproto_l4proto, -EPROTO, "Test EPROTO for l4proto != TCP or UDP");
	ASSERT_EQ(skel->bss->test_enonet_netns_id, -ENONET, "Test ENONET for bad but valid netns_id");
	ASSERT_EQ(skel->bss->test_enoent_lookup, -ENOENT, "Test ENOENT for failed lookup");
	ASSERT_EQ(skel->bss->test_eafnosupport, -EAFNOSUPPORT, "Test EAFNOSUPPORT for invalid len__tuple");
	ASSERT_EQ(skel->data->test_alloc_entry, 0, "Test for alloc new entry");
	ASSERT_EQ(skel->data->test_insert_entry, 0, "Test for insert new entry");
	ASSERT_EQ(skel->data->test_succ_lookup, 0, "Test for successful lookup");
	/* allow some tolerance for test_delta_timeout value to avoid races. */
	ASSERT_GT(skel->bss->test_delta_timeout, 8, "Test for min ct timeout update");
	ASSERT_LE(skel->bss->test_delta_timeout, 10, "Test for max ct timeout update");
	ASSERT_EQ(skel->bss->test_insert_lookup_mark, 77, "Test for insert and lookup mark value");
	ASSERT_EQ(skel->bss->test_status, IPS_STATUS_MASK, "Test for ct status update ");
	ASSERT_EQ(skel->data->test_exist_lookup, 0, "Test existing connection lookup");
	ASSERT_EQ(skel->bss->test_exist_lookup_mark, 43, "Test existing connection lookup ctmark");
	ASSERT_EQ(skel->data->test_snat_addr, 0, "Test for source natting");
	ASSERT_EQ(skel->data->test_dnat_addr, 0, "Test for destination natting");
	ASSERT_EQ(skel->data->test_ct_zone_id_alloc_entry, 0, "Test for alloc new entry in specified ct zone");
	ASSERT_EQ(skel->data->test_ct_zone_id_insert_entry, 0, "Test for insert new entry in specified ct zone");
	ASSERT_EQ(skel->data->test_ct_zone_id_succ_lookup, 0, "Test for successful lookup in specified ct_zone");
	ASSERT_EQ(skel->bss->test_ct_zone_dir_enoent_lookup, -ENOENT, "Test ENOENT for lookup with wrong ct zone dir");
	ASSERT_EQ(skel->bss->test_ct_zone_id_enoent_lookup, -ENOENT, "Test ENOENT for lookup in wrong ct zone");

end:
	if (client_fd != -1)
		close(client_fd);
	if (srv_client_fd != -1)
		close(srv_client_fd);
	if (srv_fd != -1)
		close(srv_fd);

	snprintf(cmd, sizeof(cmd), iptables, "-D");
	system(cmd);
	test_bpf_nf__destroy(skel);
}

static void test_bpf_nf_ct_fail(const char *prog_name, const char *err_msg)
{
	LIBBPF_OPTS(bpf_object_open_opts, opts, .kernel_log_buf = log_buf,
						.kernel_log_size = sizeof(log_buf),
						.kernel_log_level = 1);
	struct test_bpf_nf_fail *skel;
	struct bpf_program *prog;
	int ret;

	skel = test_bpf_nf_fail__open_opts(&opts);
	if (!ASSERT_OK_PTR(skel, "test_bpf_nf_fail__open"))
		return;

	prog = bpf_object__find_program_by_name(skel->obj, prog_name);
	if (!ASSERT_OK_PTR(prog, "bpf_object__find_program_by_name"))
		goto end;

	bpf_program__set_autoload(prog, true);

	ret = test_bpf_nf_fail__load(skel);
	if (!ASSERT_ERR(ret, "test_bpf_nf_fail__load must fail"))
		goto end;

	if (!ASSERT_OK_PTR(strstr(log_buf, err_msg), "expected error message")) {
		fprintf(stderr, "Expected: %s\n", err_msg);
		fprintf(stderr, "Verifier: %s\n", log_buf);
	}

end:
	test_bpf_nf_fail__destroy(skel);
}

void test_bpf_nf(void)
{
	int i;
	if (test__start_subtest("xdp-ct"))
		test_bpf_nf_ct(TEST_XDP);
	if (test__start_subtest("tc-bpf-ct"))
		test_bpf_nf_ct(TEST_TC_BPF);
	for (i = 0; i < ARRAY_SIZE(test_bpf_nf_fail_tests); i++) {
		if (test__start_subtest(test_bpf_nf_fail_tests[i].prog_name))
			test_bpf_nf_ct_fail(test_bpf_nf_fail_tests[i].prog_name,
					    test_bpf_nf_fail_tests[i].err_msg);
	}
}
