// SPDX-License-Identifier: GPL-2.0
// Copyright (c) 2018 Facebook
// Copyright (c) 2019 Cloudflare
// Copyright (c) 2020 Isovalent, Inc.
/*
 * Test that the socket assign program is able to redirect traffic towards a
 * socket, regardless of whether the port or address destination of the traffic
 * matches the port.
 */

#define _GNU_SOURCE
#include <fcntl.h>
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>

#include "test_progs.h"
#include "network_helpers.h"

#define BIND_PORT 1234
#define CONNECT_PORT 4321
#define TEST_DADDR (0xC0A80203)
#define NS_SELF "/proc/self/ns/net"
#define SERVER_MAP_PATH "/sys/fs/bpf/tc/globals/server_map"

static int stop, duration;

static bool
configure_stack(void)
{
	char tc_version[128];
	char tc_cmd[BUFSIZ];
	char *prog;
	FILE *tc;

	/* Check whether tc is built with libbpf. */
	tc = popen("tc -V", "r");
	if (CHECK_FAIL(!tc))
		return false;
	if (CHECK_FAIL(!fgets(tc_version, sizeof(tc_version), tc)))
		return false;
	if (strstr(tc_version, ", libbpf "))
		prog = "test_sk_assign_libbpf.bpf.o";
	else
		prog = "test_sk_assign.bpf.o";
	if (CHECK_FAIL(pclose(tc)))
		return false;

	/* Move to a new networking namespace */
	if (CHECK_FAIL(unshare(CLONE_NEWNET)))
		return false;

	/* Configure necessary links, routes */
	if (CHECK_FAIL(system("ip link set dev lo up")))
		return false;
	if (CHECK_FAIL(system("ip route add local default dev lo")))
		return false;
	if (CHECK_FAIL(system("ip -6 route add local default dev lo")))
		return false;

	/* Load qdisc, BPF program */
	if (CHECK_FAIL(system("tc qdisc add dev lo clsact")))
		return false;
	sprintf(tc_cmd, "%s %s %s %s %s", "tc filter add dev lo ingress bpf",
		       "direct-action object-file", prog,
		       "section tc",
		       (env.verbosity < VERBOSE_VERY) ? " 2>/dev/null" : "verbose");
	if (CHECK(system(tc_cmd), "BPF load failed;",
		  "run with -vv for more info\n"))
		return false;

	return true;
}

static in_port_t
get_port(int fd)
{
	struct sockaddr_storage ss;
	socklen_t slen = sizeof(ss);
	in_port_t port = 0;

	if (CHECK_FAIL(getsockname(fd, (struct sockaddr *)&ss, &slen)))
		return port;

	switch (ss.ss_family) {
	case AF_INET:
		port = ((struct sockaddr_in *)&ss)->sin_port;
		break;
	case AF_INET6:
		port = ((struct sockaddr_in6 *)&ss)->sin6_port;
		break;
	default:
		CHECK(1, "Invalid address family", "%d\n", ss.ss_family);
	}
	return port;
}

static ssize_t
rcv_msg(int srv_client, int type)
{
	char buf[BUFSIZ];

	if (type == SOCK_STREAM)
		return read(srv_client, &buf, sizeof(buf));
	else
		return recvfrom(srv_client, &buf, sizeof(buf), 0, NULL, NULL);
}

static int
run_test(int server_fd, const struct sockaddr *addr, socklen_t len, int type)
{
	int client = -1, srv_client = -1;
	char buf[] = "testing";
	in_port_t port;
	int ret = 1;

	client = connect_to_addr(type, (struct sockaddr_storage *)addr, len, NULL);
	if (client == -1) {
		perror("Cannot connect to server");
		goto out;
	}

	if (type == SOCK_STREAM) {
		srv_client = accept(server_fd, NULL, NULL);
		if (CHECK_FAIL(srv_client == -1)) {
			perror("Can't accept connection");
			goto out;
		}
	} else {
		srv_client = server_fd;
	}
	if (CHECK_FAIL(write(client, buf, sizeof(buf)) != sizeof(buf))) {
		perror("Can't write on client");
		goto out;
	}
	if (CHECK_FAIL(rcv_msg(srv_client, type) != sizeof(buf))) {
		perror("Can't read on server");
		goto out;
	}

	port = get_port(srv_client);
	if (CHECK_FAIL(!port))
		goto out;
	/* SOCK_STREAM is connected via accept(), so the server's local address
	 * will be the CONNECT_PORT rather than the BIND port that corresponds
	 * to the listen socket. SOCK_DGRAM on the other hand is connectionless
	 * so we can't really do the same check there; the server doesn't ever
	 * create a socket with CONNECT_PORT.
	 */
	if (type == SOCK_STREAM &&
	    CHECK(port != htons(CONNECT_PORT), "Expected", "port %u but got %u",
		  CONNECT_PORT, ntohs(port)))
		goto out;
	else if (type == SOCK_DGRAM &&
		 CHECK(port != htons(BIND_PORT), "Expected",
		       "port %u but got %u", BIND_PORT, ntohs(port)))
		goto out;

	ret = 0;
out:
	close(client);
	if (srv_client != server_fd)
		close(srv_client);
	if (ret)
		WRITE_ONCE(stop, 1);
	return ret;
}

static void
prepare_addr(struct sockaddr *addr, int family, __u16 port, bool rewrite_addr)
{
	struct sockaddr_in *addr4;
	struct sockaddr_in6 *addr6;

	switch (family) {
	case AF_INET:
		addr4 = (struct sockaddr_in *)addr;
		memset(addr4, 0, sizeof(*addr4));
		addr4->sin_family = family;
		addr4->sin_port = htons(port);
		if (rewrite_addr)
			addr4->sin_addr.s_addr = htonl(TEST_DADDR);
		else
			addr4->sin_addr.s_addr = htonl(INADDR_LOOPBACK);
		break;
	case AF_INET6:
		addr6 = (struct sockaddr_in6 *)addr;
		memset(addr6, 0, sizeof(*addr6));
		addr6->sin6_family = family;
		addr6->sin6_port = htons(port);
		addr6->sin6_addr = in6addr_loopback;
		if (rewrite_addr)
			addr6->sin6_addr.s6_addr32[3] = htonl(TEST_DADDR);
		break;
	default:
		fprintf(stderr, "Invalid family %d", family);
	}
}

struct test_sk_cfg {
	const char *name;
	int family;
	struct sockaddr *addr;
	socklen_t len;
	int type;
	bool rewrite_addr;
};

#define TEST(NAME, FAMILY, TYPE, REWRITE)				\
{									\
	.name = NAME,							\
	.family = FAMILY,						\
	.addr = (FAMILY == AF_INET) ? (struct sockaddr *)&addr4		\
				    : (struct sockaddr *)&addr6,	\
	.len = (FAMILY == AF_INET) ? sizeof(addr4) : sizeof(addr6),	\
	.type = TYPE,							\
	.rewrite_addr = REWRITE,					\
}

void test_sk_assign(void)
{
	struct sockaddr_in addr4;
	struct sockaddr_in6 addr6;
	struct test_sk_cfg tests[] = {
		TEST("ipv4 tcp port redir", AF_INET, SOCK_STREAM, false),
		TEST("ipv4 tcp addr redir", AF_INET, SOCK_STREAM, true),
		TEST("ipv6 tcp port redir", AF_INET6, SOCK_STREAM, false),
		TEST("ipv6 tcp addr redir", AF_INET6, SOCK_STREAM, true),
		TEST("ipv4 udp port redir", AF_INET, SOCK_DGRAM, false),
		TEST("ipv4 udp addr redir", AF_INET, SOCK_DGRAM, true),
		TEST("ipv6 udp port redir", AF_INET6, SOCK_DGRAM, false),
		TEST("ipv6 udp addr redir", AF_INET6, SOCK_DGRAM, true),
	};
	__s64 server = -1;
	int server_map;
	int self_net;
	int i;

	self_net = open(NS_SELF, O_RDONLY);
	if (CHECK_FAIL(self_net < 0)) {
		perror("Unable to open "NS_SELF);
		return;
	}

	if (!configure_stack()) {
		perror("configure_stack");
		goto cleanup;
	}

	server_map = bpf_obj_get(SERVER_MAP_PATH);
	if (CHECK_FAIL(server_map < 0)) {
		perror("Unable to open " SERVER_MAP_PATH);
		goto cleanup;
	}

	for (i = 0; i < ARRAY_SIZE(tests) && !READ_ONCE(stop); i++) {
		struct test_sk_cfg *test = &tests[i];
		const struct sockaddr *addr;
		const int zero = 0;
		int err;

		if (!test__start_subtest(test->name))
			continue;
		prepare_addr(test->addr, test->family, BIND_PORT, false);
		addr = (const struct sockaddr *)test->addr;
		server = start_server_addr(test->type,
					   (const struct sockaddr_storage *)addr,
					   test->len, NULL);
		if (server == -1)
			goto close;

		err = bpf_map_update_elem(server_map, &zero, &server, BPF_ANY);
		if (CHECK_FAIL(err)) {
			perror("Unable to update server_map");
			goto close;
		}

		/* connect to unbound ports */
		prepare_addr(test->addr, test->family, CONNECT_PORT,
			     test->rewrite_addr);
		if (run_test(server, addr, test->len, test->type))
			goto close;

		close(server);
		server = -1;
	}

close:
	close(server);
	close(server_map);
cleanup:
	if (CHECK_FAIL(unlink(SERVER_MAP_PATH)))
		perror("Unable to unlink " SERVER_MAP_PATH);
	if (CHECK_FAIL(setns(self_net, CLONE_NEWNET)))
		perror("Failed to setns("NS_SELF")");
	close(self_net);
}
