// SPDX-License-Identifier: GPL-2.0
/* Copyright (c) 2020 Jesper Dangaard Brouer */

#include <linux/if_link.h> /* before test_progs.h, avoid bpf_util.h redefines */
#include <test_progs.h>
#include "test_check_mtu.skel.h"
#include "network_helpers.h"

#include <stdlib.h>
#include <inttypes.h>

#define IFINDEX_LO 1

static __u32 duration; /* Hint: needed for CHECK macro */

static int read_mtu_device_lo(void)
{
	const char *filename = "/sys/class/net/lo/mtu";
	char buf[11] = {};
	int value, n, fd;

	fd = open(filename, 0, O_RDONLY);
	if (fd == -1)
		return -1;

	n = read(fd, buf, sizeof(buf));
	close(fd);

	if (n == -1)
		return -2;

	value = strtoimax(buf, NULL, 10);
	if (errno == ERANGE)
		return -3;

	return value;
}

static void test_check_mtu_xdp_attach(void)
{
	struct bpf_link_info link_info;
	__u32 link_info_len = sizeof(link_info);
	struct test_check_mtu *skel;
	struct bpf_program *prog;
	struct bpf_link *link;
	int err = 0;
	int fd;

	skel = test_check_mtu__open_and_load();
	if (CHECK(!skel, "open and load skel", "failed"))
		return; /* Exit if e.g. helper unknown to kernel */

	prog = skel->progs.xdp_use_helper_basic;

	link = bpf_program__attach_xdp(prog, IFINDEX_LO);
	if (CHECK(IS_ERR(link), "link_attach", "failed: %ld\n", PTR_ERR(link)))
		goto out;
	skel->links.xdp_use_helper_basic = link;

	memset(&link_info, 0, sizeof(link_info));
	fd = bpf_link__fd(link);
	err = bpf_obj_get_info_by_fd(fd, &link_info, &link_info_len);
	if (CHECK(err, "link_info", "failed: %d\n", err))
		goto out;

	CHECK(link_info.type != BPF_LINK_TYPE_XDP, "link_type",
	      "got %u != exp %u\n", link_info.type, BPF_LINK_TYPE_XDP);
	CHECK(link_info.xdp.ifindex != IFINDEX_LO, "link_ifindex",
	      "got %u != exp %u\n", link_info.xdp.ifindex, IFINDEX_LO);

	err = bpf_link__detach(link);
	CHECK(err, "link_detach", "failed %d\n", err);

out:
	test_check_mtu__destroy(skel);
}

static void test_check_mtu_run_xdp(struct test_check_mtu *skel,
				   struct bpf_program *prog,
				   __u32 mtu_expect)
{
	const char *prog_name = bpf_program__name(prog);
	int retval_expect = XDP_PASS;
	__u32 mtu_result = 0;
	char buf[256] = {};
	int err;
	struct bpf_prog_test_run_attr tattr = {
		.repeat = 1,
		.data_in = &pkt_v4,
		.data_size_in = sizeof(pkt_v4),
		.data_out = buf,
		.data_size_out = sizeof(buf),
		.prog_fd = bpf_program__fd(prog),
	};

	err = bpf_prog_test_run_xattr(&tattr);
	CHECK_ATTR(err != 0, "bpf_prog_test_run",
		   "prog_name:%s (err %d errno %d retval %d)\n",
		   prog_name, err, errno, tattr.retval);

	CHECK(tattr.retval != retval_expect, "retval",
	      "progname:%s unexpected retval=%d expected=%d\n",
	      prog_name, tattr.retval, retval_expect);

	/* Extract MTU that BPF-prog got */
	mtu_result = skel->bss->global_bpf_mtu_xdp;
	ASSERT_EQ(mtu_result, mtu_expect, "MTU-compare-user");
}


static void test_check_mtu_xdp(__u32 mtu, __u32 ifindex)
{
	struct test_check_mtu *skel;
	int err;

	skel = test_check_mtu__open();
	if (CHECK(!skel, "skel_open", "failed"))
		return;

	/* Update "constants" in BPF-prog *BEFORE* libbpf load */
	skel->rodata->GLOBAL_USER_MTU = mtu;
	skel->rodata->GLOBAL_USER_IFINDEX = ifindex;

	err = test_check_mtu__load(skel);
	if (CHECK(err, "skel_load", "failed: %d\n", err))
		goto cleanup;

	test_check_mtu_run_xdp(skel, skel->progs.xdp_use_helper, mtu);
	test_check_mtu_run_xdp(skel, skel->progs.xdp_exceed_mtu, mtu);
	test_check_mtu_run_xdp(skel, skel->progs.xdp_minus_delta, mtu);
	test_check_mtu_run_xdp(skel, skel->progs.xdp_input_len, mtu);
	test_check_mtu_run_xdp(skel, skel->progs.xdp_input_len_exceed, mtu);

cleanup:
	test_check_mtu__destroy(skel);
}

static void test_check_mtu_run_tc(struct test_check_mtu *skel,
				  struct bpf_program *prog,
				  __u32 mtu_expect)
{
	const char *prog_name = bpf_program__name(prog);
	int retval_expect = BPF_OK;
	__u32 mtu_result = 0;
	char buf[256] = {};
	int err;
	struct bpf_prog_test_run_attr tattr = {
		.repeat = 1,
		.data_in = &pkt_v4,
		.data_size_in = sizeof(pkt_v4),
		.data_out = buf,
		.data_size_out = sizeof(buf),
		.prog_fd = bpf_program__fd(prog),
	};

	err = bpf_prog_test_run_xattr(&tattr);
	CHECK_ATTR(err != 0, "bpf_prog_test_run",
		   "prog_name:%s (err %d errno %d retval %d)\n",
		   prog_name, err, errno, tattr.retval);

	CHECK(tattr.retval != retval_expect, "retval",
	      "progname:%s unexpected retval=%d expected=%d\n",
	      prog_name, tattr.retval, retval_expect);

	/* Extract MTU that BPF-prog got */
	mtu_result = skel->bss->global_bpf_mtu_tc;
	ASSERT_EQ(mtu_result, mtu_expect, "MTU-compare-user");
}


static void test_check_mtu_tc(__u32 mtu, __u32 ifindex)
{
	struct test_check_mtu *skel;
	int err;

	skel = test_check_mtu__open();
	if (CHECK(!skel, "skel_open", "failed"))
		return;

	/* Update "constants" in BPF-prog *BEFORE* libbpf load */
	skel->rodata->GLOBAL_USER_MTU = mtu;
	skel->rodata->GLOBAL_USER_IFINDEX = ifindex;

	err = test_check_mtu__load(skel);
	if (CHECK(err, "skel_load", "failed: %d\n", err))
		goto cleanup;

	test_check_mtu_run_tc(skel, skel->progs.tc_use_helper, mtu);
	test_check_mtu_run_tc(skel, skel->progs.tc_exceed_mtu, mtu);
	test_check_mtu_run_tc(skel, skel->progs.tc_exceed_mtu_da, mtu);
	test_check_mtu_run_tc(skel, skel->progs.tc_minus_delta, mtu);
	test_check_mtu_run_tc(skel, skel->progs.tc_input_len, mtu);
	test_check_mtu_run_tc(skel, skel->progs.tc_input_len_exceed, mtu);
cleanup:
	test_check_mtu__destroy(skel);
}

void test_check_mtu(void)
{
	__u32 mtu_lo;

	if (test__start_subtest("bpf_check_mtu XDP-attach"))
		test_check_mtu_xdp_attach();

	mtu_lo = read_mtu_device_lo();
	if (CHECK(mtu_lo < 0, "reading MTU value", "failed (err:%d)", mtu_lo))
		return;

	if (test__start_subtest("bpf_check_mtu XDP-run"))
		test_check_mtu_xdp(mtu_lo, 0);

	if (test__start_subtest("bpf_check_mtu XDP-run ifindex-lookup"))
		test_check_mtu_xdp(mtu_lo, IFINDEX_LO);

	if (test__start_subtest("bpf_check_mtu TC-run"))
		test_check_mtu_tc(mtu_lo, 0);

	if (test__start_subtest("bpf_check_mtu TC-run ifindex-lookup"))
		test_check_mtu_tc(mtu_lo, IFINDEX_LO);
}
