// SPDX-License-Identifier: GPL-2.0

#include <test_progs.h>
#include "cgroup_helpers.h"
#include "network_helpers.h"

static int verify_ports(int family, int fd,
			__u16 expected_local, __u16 expected_peer)
{
	struct sockaddr_storage addr;
	socklen_t len = sizeof(addr);
	__u16 port;

	if (getsockname(fd, (struct sockaddr *)&addr, &len)) {
		log_err("Failed to get server addr");
		return -1;
	}

	if (family == AF_INET)
		port = ((struct sockaddr_in *)&addr)->sin_port;
	else
		port = ((struct sockaddr_in6 *)&addr)->sin6_port;

	if (ntohs(port) != expected_local) {
		log_err("Unexpected local port %d, expected %d", ntohs(port),
			expected_local);
		return -1;
	}

	if (getpeername(fd, (struct sockaddr *)&addr, &len)) {
		log_err("Failed to get peer addr");
		return -1;
	}

	if (family == AF_INET)
		port = ((struct sockaddr_in *)&addr)->sin_port;
	else
		port = ((struct sockaddr_in6 *)&addr)->sin6_port;

	if (ntohs(port) != expected_peer) {
		log_err("Unexpected peer port %d, expected %d", ntohs(port),
			expected_peer);
		return -1;
	}

	return 0;
}

static int run_test(int cgroup_fd, int server_fd, int family, int type)
{
	bool v4 = family == AF_INET;
	__u16 expected_local_port = v4 ? 22222 : 22223;
	__u16 expected_peer_port = 60000;
	struct bpf_program *prog;
	struct bpf_object *obj;
	const char *obj_file = v4 ? "connect_force_port4.bpf.o" : "connect_force_port6.bpf.o";
	int fd, err;
	__u32 duration = 0;

	obj = bpf_object__open_file(obj_file, NULL);
	if (!ASSERT_OK_PTR(obj, "bpf_obj_open"))
		return -1;

	err = bpf_object__load(obj);
	if (!ASSERT_OK(err, "bpf_obj_load")) {
		err = -EIO;
		goto close_bpf_object;
	}

	prog = bpf_object__find_program_by_name(obj, v4 ?
						"connect4" :
						"connect6");
	if (CHECK(!prog, "find_prog", "connect prog not found\n")) {
		err = -EIO;
		goto close_bpf_object;
	}

	err = bpf_prog_attach(bpf_program__fd(prog), cgroup_fd, v4 ?
			      BPF_CGROUP_INET4_CONNECT :
			      BPF_CGROUP_INET6_CONNECT, 0);
	if (err) {
		log_err("Failed to attach BPF program");
		goto close_bpf_object;
	}

	prog = bpf_object__find_program_by_name(obj, v4 ?
						"getpeername4" :
						"getpeername6");
	if (CHECK(!prog, "find_prog", "getpeername prog not found\n")) {
		err = -EIO;
		goto close_bpf_object;
	}

	err = bpf_prog_attach(bpf_program__fd(prog), cgroup_fd, v4 ?
			      BPF_CGROUP_INET4_GETPEERNAME :
			      BPF_CGROUP_INET6_GETPEERNAME, 0);
	if (err) {
		log_err("Failed to attach BPF program");
		goto close_bpf_object;
	}

	prog = bpf_object__find_program_by_name(obj, v4 ?
						"getsockname4" :
						"getsockname6");
	if (CHECK(!prog, "find_prog", "getsockname prog not found\n")) {
		err = -EIO;
		goto close_bpf_object;
	}

	err = bpf_prog_attach(bpf_program__fd(prog), cgroup_fd, v4 ?
			      BPF_CGROUP_INET4_GETSOCKNAME :
			      BPF_CGROUP_INET6_GETSOCKNAME, 0);
	if (err) {
		log_err("Failed to attach BPF program");
		goto close_bpf_object;
	}

	fd = connect_to_fd(server_fd, 0);
	if (fd < 0) {
		err = -1;
		goto close_bpf_object;
	}

	err = verify_ports(family, fd, expected_local_port,
			   expected_peer_port);
	close(fd);

close_bpf_object:
	bpf_object__close(obj);
	return err;
}

void test_connect_force_port(void)
{
	int server_fd, cgroup_fd;

	cgroup_fd = test__join_cgroup("/connect_force_port");
	if (CHECK_FAIL(cgroup_fd < 0))
		return;

	server_fd = start_server(AF_INET, SOCK_STREAM, NULL, 60123, 0);
	if (CHECK_FAIL(server_fd < 0))
		goto close_cgroup_fd;
	CHECK_FAIL(run_test(cgroup_fd, server_fd, AF_INET, SOCK_STREAM));
	close(server_fd);

	server_fd = start_server(AF_INET6, SOCK_STREAM, NULL, 60124, 0);
	if (CHECK_FAIL(server_fd < 0))
		goto close_cgroup_fd;
	CHECK_FAIL(run_test(cgroup_fd, server_fd, AF_INET6, SOCK_STREAM));
	close(server_fd);

	server_fd = start_server(AF_INET, SOCK_DGRAM, NULL, 60123, 0);
	if (CHECK_FAIL(server_fd < 0))
		goto close_cgroup_fd;
	CHECK_FAIL(run_test(cgroup_fd, server_fd, AF_INET, SOCK_DGRAM));
	close(server_fd);

	server_fd = start_server(AF_INET6, SOCK_DGRAM, NULL, 60124, 0);
	if (CHECK_FAIL(server_fd < 0))
		goto close_cgroup_fd;
	CHECK_FAIL(run_test(cgroup_fd, server_fd, AF_INET6, SOCK_DGRAM));
	close(server_fd);

close_cgroup_fd:
	close(cgroup_fd);
}
