// SPDX-License-Identifier: GPL-2.0

#include <test_progs.h>
#include "cgroup_helpers.h"
#include "testing_helpers.h"
#include "test_cgroup_link.skel.h"

static __u32 duration = 0;
#define PING_CMD	"ping -q -c1 -w1 127.0.0.1 > /dev/null"

static struct test_cgroup_link *skel = NULL;

int ping_and_check(int exp_calls, int exp_alt_calls)
{
	skel->bss->calls = 0;
	skel->bss->alt_calls = 0;
	CHECK_FAIL(system(PING_CMD));
	if (CHECK(skel->bss->calls != exp_calls, "call_cnt",
		  "exp %d, got %d\n", exp_calls, skel->bss->calls))
		return -EINVAL;
	if (CHECK(skel->bss->alt_calls != exp_alt_calls, "alt_call_cnt",
		  "exp %d, got %d\n", exp_alt_calls, skel->bss->alt_calls))
		return -EINVAL;
	return 0;
}

void serial_test_cgroup_link(void)
{
	struct {
		const char *path;
		int fd;
	} cgs[] = {
		{ "/cg1" },
		{ "/cg1/cg2" },
		{ "/cg1/cg2/cg3" },
		{ "/cg1/cg2/cg3/cg4" },
	};
	int last_cg = ARRAY_SIZE(cgs) - 1, cg_nr = ARRAY_SIZE(cgs);
	DECLARE_LIBBPF_OPTS(bpf_link_update_opts, link_upd_opts);
	struct bpf_link *links[ARRAY_SIZE(cgs)] = {}, *tmp_link;
	__u32 prog_ids[ARRAY_SIZE(cgs)], prog_cnt = 0, attach_flags, prog_id;
	struct bpf_link_info info;
	int i = 0, err, prog_fd;
	bool detach_legacy = false;

	skel = test_cgroup_link__open_and_load();
	if (CHECK(!skel, "skel_open_load", "failed to open/load skeleton\n"))
		return;
	prog_fd = bpf_program__fd(skel->progs.egress);

	err = setup_cgroup_environment();
	if (CHECK(err, "cg_init", "failed: %d\n", err))
		goto cleanup;

	for (i = 0; i < cg_nr; i++) {
		cgs[i].fd = create_and_get_cgroup(cgs[i].path);
		if (!ASSERT_GE(cgs[i].fd, 0, "cg_create"))
			goto cleanup;
	}

	err = join_cgroup(cgs[last_cg].path);
	if (CHECK(err, "cg_join", "fail: %d\n", err))
		goto cleanup;

	for (i = 0; i < cg_nr; i++) {
		links[i] = bpf_program__attach_cgroup(skel->progs.egress,
						      cgs[i].fd);
		if (!ASSERT_OK_PTR(links[i], "cg_attach"))
			goto cleanup;
	}

	ping_and_check(cg_nr, 0);

	/* query the number of attached progs and attach flags in root cg */
	err = bpf_prog_query(cgs[0].fd, BPF_CGROUP_INET_EGRESS,
			     0, &attach_flags, NULL, &prog_cnt);
	CHECK_FAIL(err);
	CHECK_FAIL(attach_flags != BPF_F_ALLOW_MULTI);
	if (CHECK(prog_cnt != 1, "effect_cnt", "exp %d, got %d\n", 1, prog_cnt))
		goto cleanup;

	/* query the number of effective progs in last cg */
	err = bpf_prog_query(cgs[last_cg].fd, BPF_CGROUP_INET_EGRESS,
			     BPF_F_QUERY_EFFECTIVE, NULL, NULL,
			     &prog_cnt);
	CHECK_FAIL(err);
	if (CHECK(prog_cnt != cg_nr, "effect_cnt", "exp %d, got %d\n",
		  cg_nr, prog_cnt))
		goto cleanup;

	/* query the effective prog IDs in last cg */
	err = bpf_prog_query(cgs[last_cg].fd, BPF_CGROUP_INET_EGRESS,
			     BPF_F_QUERY_EFFECTIVE, NULL, prog_ids,
			     &prog_cnt);
	CHECK_FAIL(err);
	if (CHECK(prog_cnt != cg_nr, "effect_cnt", "exp %d, got %d\n",
		  cg_nr, prog_cnt))
		goto cleanup;
	for (i = 1; i < prog_cnt; i++) {
		CHECK(prog_ids[i - 1] != prog_ids[i], "prog_id_check",
		      "idx %d, prev id %d, cur id %d\n",
		      i, prog_ids[i - 1], prog_ids[i]);
	}

	/* detach bottom program and ping again */
	bpf_link__destroy(links[last_cg]);
	links[last_cg] = NULL;

	ping_and_check(cg_nr - 1, 0);

	/* mix in with non link-based multi-attachments */
	err = bpf_prog_attach(prog_fd, cgs[last_cg].fd,
			      BPF_CGROUP_INET_EGRESS, BPF_F_ALLOW_MULTI);
	if (CHECK(err, "cg_attach_legacy", "errno=%d\n", errno))
		goto cleanup;
	detach_legacy = true;

	links[last_cg] = bpf_program__attach_cgroup(skel->progs.egress,
						    cgs[last_cg].fd);
	if (!ASSERT_OK_PTR(links[last_cg], "cg_attach"))
		goto cleanup;

	ping_and_check(cg_nr + 1, 0);

	/* detach link */
	bpf_link__destroy(links[last_cg]);
	links[last_cg] = NULL;

	/* detach legacy */
	err = bpf_prog_detach2(prog_fd, cgs[last_cg].fd, BPF_CGROUP_INET_EGRESS);
	if (CHECK(err, "cg_detach_legacy", "errno=%d\n", errno))
		goto cleanup;
	detach_legacy = false;

	/* attach legacy exclusive prog attachment */
	err = bpf_prog_attach(prog_fd, cgs[last_cg].fd,
			      BPF_CGROUP_INET_EGRESS, 0);
	if (CHECK(err, "cg_attach_exclusive", "errno=%d\n", errno))
		goto cleanup;
	detach_legacy = true;

	/* attempt to mix in with multi-attach bpf_link */
	tmp_link = bpf_program__attach_cgroup(skel->progs.egress,
					      cgs[last_cg].fd);
	if (!ASSERT_ERR_PTR(tmp_link, "cg_attach_fail")) {
		bpf_link__destroy(tmp_link);
		goto cleanup;
	}

	ping_and_check(cg_nr, 0);

	/* detach */
	err = bpf_prog_detach2(prog_fd, cgs[last_cg].fd, BPF_CGROUP_INET_EGRESS);
	if (CHECK(err, "cg_detach_legacy", "errno=%d\n", errno))
		goto cleanup;
	detach_legacy = false;

	ping_and_check(cg_nr - 1, 0);

	/* attach back link-based one */
	links[last_cg] = bpf_program__attach_cgroup(skel->progs.egress,
						    cgs[last_cg].fd);
	if (!ASSERT_OK_PTR(links[last_cg], "cg_attach"))
		goto cleanup;

	ping_and_check(cg_nr, 0);

	/* check legacy exclusive prog can't be attached */
	err = bpf_prog_attach(prog_fd, cgs[last_cg].fd,
			      BPF_CGROUP_INET_EGRESS, 0);
	if (CHECK(!err, "cg_attach_exclusive", "unexpected success")) {
		bpf_prog_detach2(prog_fd, cgs[last_cg].fd, BPF_CGROUP_INET_EGRESS);
		goto cleanup;
	}

	/* replace BPF programs inside their links for all but first link */
	for (i = 1; i < cg_nr; i++) {
		err = bpf_link__update_program(links[i], skel->progs.egress_alt);
		if (CHECK(err, "prog_upd", "link #%d\n", i))
			goto cleanup;
	}

	ping_and_check(1, cg_nr - 1);

	/* Attempt program update with wrong expected BPF program */
	link_upd_opts.old_prog_fd = bpf_program__fd(skel->progs.egress_alt);
	link_upd_opts.flags = BPF_F_REPLACE;
	err = bpf_link_update(bpf_link__fd(links[0]),
			      bpf_program__fd(skel->progs.egress_alt),
			      &link_upd_opts);
	if (CHECK(err == 0 || errno != EPERM, "prog_cmpxchg1",
		  "unexpectedly succeeded, err %d, errno %d\n", err, -errno))
		goto cleanup;

	/* Compare-exchange single link program from egress to egress_alt */
	link_upd_opts.old_prog_fd = bpf_program__fd(skel->progs.egress);
	link_upd_opts.flags = BPF_F_REPLACE;
	err = bpf_link_update(bpf_link__fd(links[0]),
			      bpf_program__fd(skel->progs.egress_alt),
			      &link_upd_opts);
	if (CHECK(err, "prog_cmpxchg2", "errno %d\n", -errno))
		goto cleanup;

	/* ping */
	ping_and_check(0, cg_nr);

	/* close cgroup FDs before detaching links */
	for (i = 0; i < cg_nr; i++) {
		if (cgs[i].fd > 0) {
			close(cgs[i].fd);
			cgs[i].fd = -1;
		}
	}

	/* BPF programs should still get called */
	ping_and_check(0, cg_nr);

	prog_id = link_info_prog_id(links[0], &info);
	CHECK(prog_id == 0, "link_info", "failed\n");
	CHECK(info.cgroup.cgroup_id == 0, "cgroup_id", "unexpected %llu\n", info.cgroup.cgroup_id);

	err = bpf_link__detach(links[0]);
	if (CHECK(err, "link_detach", "failed %d\n", err))
		goto cleanup;

	/* cgroup_id should be zero in link_info */
	prog_id = link_info_prog_id(links[0], &info);
	CHECK(prog_id == 0, "link_info", "failed\n");
	CHECK(info.cgroup.cgroup_id != 0, "cgroup_id", "unexpected %llu\n", info.cgroup.cgroup_id);

	/* First BPF program shouldn't be called anymore */
	ping_and_check(0, cg_nr - 1);

	/* leave cgroup and remove them, don't detach programs */
	cleanup_cgroup_environment();

	/* BPF programs should have been auto-detached */
	ping_and_check(0, 0);

cleanup:
	if (detach_legacy)
		bpf_prog_detach2(prog_fd, cgs[last_cg].fd,
				 BPF_CGROUP_INET_EGRESS);

	for (i = 0; i < cg_nr; i++) {
		bpf_link__destroy(links[i]);
	}
	test_cgroup_link__destroy(skel);

	for (i = 0; i < cg_nr; i++) {
		if (cgs[i].fd > 0)
			close(cgs[i].fd);
	}
	cleanup_cgroup_environment();
}
