// SPDX-License-Identifier: GPL-2.0
/* Copyright (c) 2021 Facebook */
#define _GNU_SOURCE
#include <sched.h>
#include <test_progs.h>
#include "network_helpers.h"
#include "bpf_dctcp.skel.h"
#include "bpf_cubic.skel.h"
#include "bpf_iter_setsockopt.skel.h"

static int create_netns(void)
{
	if (!ASSERT_OK(unshare(CLONE_NEWNET), "create netns"))
		return -1;

	if (!ASSERT_OK(system("ip link set dev lo up"), "bring up lo"))
		return -1;

	return 0;
}

static unsigned int set_bpf_cubic(int *fds, unsigned int nr_fds)
{
	unsigned int i;

	for (i = 0; i < nr_fds; i++) {
		if (setsockopt(fds[i], SOL_TCP, TCP_CONGESTION, "bpf_cubic",
			       sizeof("bpf_cubic")))
			return i;
	}

	return nr_fds;
}

static unsigned int check_bpf_dctcp(int *fds, unsigned int nr_fds)
{
	char tcp_cc[16];
	socklen_t optlen = sizeof(tcp_cc);
	unsigned int i;

	for (i = 0; i < nr_fds; i++) {
		if (getsockopt(fds[i], SOL_TCP, TCP_CONGESTION,
			       tcp_cc, &optlen) ||
		    strcmp(tcp_cc, "bpf_dctcp"))
			return i;
	}

	return nr_fds;
}

static int *make_established(int listen_fd, unsigned int nr_est,
			     int **paccepted_fds)
{
	int *est_fds, *accepted_fds;
	unsigned int i;

	est_fds = malloc(sizeof(*est_fds) * nr_est);
	if (!est_fds)
		return NULL;

	accepted_fds = malloc(sizeof(*accepted_fds) * nr_est);
	if (!accepted_fds) {
		free(est_fds);
		return NULL;
	}

	for (i = 0; i < nr_est; i++) {
		est_fds[i] = connect_to_fd(listen_fd, 0);
		if (est_fds[i] == -1)
			break;
		if (set_bpf_cubic(&est_fds[i], 1) != 1) {
			close(est_fds[i]);
			break;
		}

		accepted_fds[i] = accept(listen_fd, NULL, 0);
		if (accepted_fds[i] == -1) {
			close(est_fds[i]);
			break;
		}
	}

	if (!ASSERT_EQ(i, nr_est, "create established fds")) {
		free_fds(accepted_fds, i);
		free_fds(est_fds, i);
		return NULL;
	}

	*paccepted_fds = accepted_fds;
	return est_fds;
}

static unsigned short get_local_port(int fd)
{
	struct sockaddr_in6 addr;
	socklen_t addrlen = sizeof(addr);

	if (!getsockname(fd, &addr, &addrlen))
		return ntohs(addr.sin6_port);

	return 0;
}

static void do_bpf_iter_setsockopt(struct bpf_iter_setsockopt *iter_skel,
				   bool random_retry)
{
	int *reuse_listen_fds = NULL, *accepted_fds = NULL, *est_fds = NULL;
	unsigned int nr_reuse_listens = 256, nr_est = 256;
	int err, iter_fd = -1, listen_fd = -1;
	char buf;

	/* Prepare non-reuseport listen_fd */
	listen_fd = start_server(AF_INET6, SOCK_STREAM, "::1", 0, 0);
	if (!ASSERT_GE(listen_fd, 0, "start_server"))
		return;
	if (!ASSERT_EQ(set_bpf_cubic(&listen_fd, 1), 1,
		       "set listen_fd to cubic"))
		goto done;
	iter_skel->bss->listen_hport = get_local_port(listen_fd);
	if (!ASSERT_NEQ(iter_skel->bss->listen_hport, 0,
			"get_local_port(listen_fd)"))
		goto done;

	/* Connect to non-reuseport listen_fd */
	est_fds = make_established(listen_fd, nr_est, &accepted_fds);
	if (!ASSERT_OK_PTR(est_fds, "create established"))
		goto done;

	/* Prepare reuseport listen fds */
	reuse_listen_fds = start_reuseport_server(AF_INET6, SOCK_STREAM,
						  "::1", 0, 0,
						  nr_reuse_listens);
	if (!ASSERT_OK_PTR(reuse_listen_fds, "start_reuseport_server"))
		goto done;
	if (!ASSERT_EQ(set_bpf_cubic(reuse_listen_fds, nr_reuse_listens),
		       nr_reuse_listens, "set reuse_listen_fds to cubic"))
		goto done;
	iter_skel->bss->reuse_listen_hport = get_local_port(reuse_listen_fds[0]);
	if (!ASSERT_NEQ(iter_skel->bss->reuse_listen_hport, 0,
			"get_local_port(reuse_listen_fds[0])"))
		goto done;

	/* Run bpf tcp iter to switch from bpf_cubic to bpf_dctcp */
	iter_skel->bss->random_retry = random_retry;
	iter_fd = bpf_iter_create(bpf_link__fd(iter_skel->links.change_tcp_cc));
	if (!ASSERT_GE(iter_fd, 0, "create iter_fd"))
		goto done;

	while ((err = read(iter_fd, &buf, sizeof(buf))) == -1 &&
	       errno == EAGAIN)
		;
	if (!ASSERT_OK(err, "read iter error"))
		goto done;

	/* Check reuseport listen fds for dctcp */
	ASSERT_EQ(check_bpf_dctcp(reuse_listen_fds, nr_reuse_listens),
		  nr_reuse_listens,
		  "check reuse_listen_fds dctcp");

	/* Check non reuseport listen fd for dctcp */
	ASSERT_EQ(check_bpf_dctcp(&listen_fd, 1), 1,
		  "check listen_fd dctcp");

	/* Check established fds for dctcp */
	ASSERT_EQ(check_bpf_dctcp(est_fds, nr_est), nr_est,
		  "check est_fds dctcp");

	/* Check accepted fds for dctcp */
	ASSERT_EQ(check_bpf_dctcp(accepted_fds, nr_est), nr_est,
		  "check accepted_fds dctcp");

done:
	if (iter_fd != -1)
		close(iter_fd);
	if (listen_fd != -1)
		close(listen_fd);
	free_fds(reuse_listen_fds, nr_reuse_listens);
	free_fds(accepted_fds, nr_est);
	free_fds(est_fds, nr_est);
}

void serial_test_bpf_iter_setsockopt(void)
{
	struct bpf_iter_setsockopt *iter_skel = NULL;
	struct bpf_cubic *cubic_skel = NULL;
	struct bpf_dctcp *dctcp_skel = NULL;
	struct bpf_link *cubic_link = NULL;
	struct bpf_link *dctcp_link = NULL;

	if (create_netns())
		return;

	/* Load iter_skel */
	iter_skel = bpf_iter_setsockopt__open_and_load();
	if (!ASSERT_OK_PTR(iter_skel, "iter_skel"))
		return;
	iter_skel->links.change_tcp_cc = bpf_program__attach_iter(iter_skel->progs.change_tcp_cc, NULL);
	if (!ASSERT_OK_PTR(iter_skel->links.change_tcp_cc, "attach iter"))
		goto done;

	/* Load bpf_cubic */
	cubic_skel = bpf_cubic__open_and_load();
	if (!ASSERT_OK_PTR(cubic_skel, "cubic_skel"))
		goto done;
	cubic_link = bpf_map__attach_struct_ops(cubic_skel->maps.cubic);
	if (!ASSERT_OK_PTR(cubic_link, "cubic_link"))
		goto done;

	/* Load bpf_dctcp */
	dctcp_skel = bpf_dctcp__open_and_load();
	if (!ASSERT_OK_PTR(dctcp_skel, "dctcp_skel"))
		goto done;
	dctcp_link = bpf_map__attach_struct_ops(dctcp_skel->maps.dctcp);
	if (!ASSERT_OK_PTR(dctcp_link, "dctcp_link"))
		goto done;

	do_bpf_iter_setsockopt(iter_skel, true);
	do_bpf_iter_setsockopt(iter_skel, false);

done:
	bpf_link__destroy(cubic_link);
	bpf_link__destroy(dctcp_link);
	bpf_cubic__destroy(cubic_skel);
	bpf_dctcp__destroy(dctcp_skel);
	bpf_iter_setsockopt__destroy(iter_skel);
}
