// SPDX-License-Identifier: GPL-2.0
// Copyright (c) 2020 Cloudflare
/*
 * Test suite for SOCKMAP/SOCKHASH holding listening sockets.
 * Covers:
 *  1. BPF map operations - bpf_map_{update,lookup delete}_elem
 *  2. BPF redirect helpers - bpf_{sk,msg}_redirect_map
 *  3. BPF reuseport helper - bpf_sk_select_reuseport
 */

#include <linux/compiler.h>
#include <errno.h>
#include <error.h>
#include <limits.h>
#include <netinet/in.h>
#include <pthread.h>
#include <stdlib.h>
#include <string.h>
#include <sys/select.h>
#include <unistd.h>
#include <linux/vm_sockets.h>

#include <bpf/bpf.h>
#include <bpf/libbpf.h>

#include "bpf_util.h"
#include "test_progs.h"
#include "test_sockmap_listen.skel.h"

#include "sockmap_helpers.h"

static void test_insert_invalid(struct test_sockmap_listen *skel __always_unused,
				int family, int sotype, int mapfd)
{
	u32 key = 0;
	u64 value;
	int err;

	value = -1;
	err = bpf_map_update_elem(mapfd, &key, &value, BPF_NOEXIST);
	if (!err || errno != EINVAL)
		FAIL_ERRNO("map_update: expected EINVAL");

	value = INT_MAX;
	err = bpf_map_update_elem(mapfd, &key, &value, BPF_NOEXIST);
	if (!err || errno != EBADF)
		FAIL_ERRNO("map_update: expected EBADF");
}

static void test_insert_opened(struct test_sockmap_listen *skel __always_unused,
			       int family, int sotype, int mapfd)
{
	u32 key = 0;
	u64 value;
	int err, s;

	s = xsocket(family, sotype, 0);
	if (s == -1)
		return;

	errno = 0;
	value = s;
	err = bpf_map_update_elem(mapfd, &key, &value, BPF_NOEXIST);
	if (sotype == SOCK_STREAM) {
		if (!err || errno != EOPNOTSUPP)
			FAIL_ERRNO("map_update: expected EOPNOTSUPP");
	} else if (err)
		FAIL_ERRNO("map_update: expected success");
	xclose(s);
}

static void test_insert_bound(struct test_sockmap_listen *skel __always_unused,
			      int family, int sotype, int mapfd)
{
	struct sockaddr_storage addr;
	socklen_t len = 0;
	u32 key = 0;
	u64 value;
	int err, s;

	init_addr_loopback(family, &addr, &len);

	s = xsocket(family, sotype, 0);
	if (s == -1)
		return;

	err = xbind(s, sockaddr(&addr), len);
	if (err)
		goto close;

	errno = 0;
	value = s;
	err = bpf_map_update_elem(mapfd, &key, &value, BPF_NOEXIST);
	if (!err || errno != EOPNOTSUPP)
		FAIL_ERRNO("map_update: expected EOPNOTSUPP");
close:
	xclose(s);
}

static void test_insert(struct test_sockmap_listen *skel __always_unused,
			int family, int sotype, int mapfd)
{
	u64 value;
	u32 key;
	int s;

	s = socket_loopback(family, sotype);
	if (s < 0)
		return;

	key = 0;
	value = s;
	xbpf_map_update_elem(mapfd, &key, &value, BPF_NOEXIST);
	xclose(s);
}

static void test_delete_after_insert(struct test_sockmap_listen *skel __always_unused,
				     int family, int sotype, int mapfd)
{
	u64 value;
	u32 key;
	int s;

	s = socket_loopback(family, sotype);
	if (s < 0)
		return;

	key = 0;
	value = s;
	xbpf_map_update_elem(mapfd, &key, &value, BPF_NOEXIST);
	xbpf_map_delete_elem(mapfd, &key);
	xclose(s);
}

static void test_delete_after_close(struct test_sockmap_listen *skel __always_unused,
				    int family, int sotype, int mapfd)
{
	int err, s;
	u64 value;
	u32 key;

	s = socket_loopback(family, sotype);
	if (s < 0)
		return;

	key = 0;
	value = s;
	xbpf_map_update_elem(mapfd, &key, &value, BPF_NOEXIST);

	xclose(s);

	errno = 0;
	err = bpf_map_delete_elem(mapfd, &key);
	if (!err || (errno != EINVAL && errno != ENOENT))
		/* SOCKMAP and SOCKHASH return different error codes */
		FAIL_ERRNO("map_delete: expected EINVAL/EINVAL");
}

static void test_lookup_after_insert(struct test_sockmap_listen *skel __always_unused,
				     int family, int sotype, int mapfd)
{
	u64 cookie, value;
	socklen_t len;
	u32 key;
	int s;

	s = socket_loopback(family, sotype);
	if (s < 0)
		return;

	key = 0;
	value = s;
	xbpf_map_update_elem(mapfd, &key, &value, BPF_NOEXIST);

	len = sizeof(cookie);
	xgetsockopt(s, SOL_SOCKET, SO_COOKIE, &cookie, &len);

	xbpf_map_lookup_elem(mapfd, &key, &value);

	if (value != cookie) {
		FAIL("map_lookup: have %#llx, want %#llx",
		     (unsigned long long)value, (unsigned long long)cookie);
	}

	xclose(s);
}

static void test_lookup_after_delete(struct test_sockmap_listen *skel __always_unused,
				     int family, int sotype, int mapfd)
{
	int err, s;
	u64 value;
	u32 key;

	s = socket_loopback(family, sotype);
	if (s < 0)
		return;

	key = 0;
	value = s;
	xbpf_map_update_elem(mapfd, &key, &value, BPF_NOEXIST);
	xbpf_map_delete_elem(mapfd, &key);

	errno = 0;
	err = bpf_map_lookup_elem(mapfd, &key, &value);
	if (!err || errno != ENOENT)
		FAIL_ERRNO("map_lookup: expected ENOENT");

	xclose(s);
}

static void test_lookup_32_bit_value(struct test_sockmap_listen *skel __always_unused,
				     int family, int sotype, int mapfd)
{
	u32 key, value32;
	int err, s;

	s = socket_loopback(family, sotype);
	if (s < 0)
		return;

	mapfd = bpf_map_create(BPF_MAP_TYPE_SOCKMAP, NULL, sizeof(key),
			       sizeof(value32), 1, NULL);
	if (mapfd < 0) {
		FAIL_ERRNO("map_create");
		goto close;
	}

	key = 0;
	value32 = s;
	xbpf_map_update_elem(mapfd, &key, &value32, BPF_NOEXIST);

	errno = 0;
	err = bpf_map_lookup_elem(mapfd, &key, &value32);
	if (!err || errno != ENOSPC)
		FAIL_ERRNO("map_lookup: expected ENOSPC");

	xclose(mapfd);
close:
	xclose(s);
}

static void test_update_existing(struct test_sockmap_listen *skel __always_unused,
				 int family, int sotype, int mapfd)
{
	int s1, s2;
	u64 value;
	u32 key;

	s1 = socket_loopback(family, sotype);
	if (s1 < 0)
		return;

	s2 = socket_loopback(family, sotype);
	if (s2 < 0)
		goto close_s1;

	key = 0;
	value = s1;
	xbpf_map_update_elem(mapfd, &key, &value, BPF_NOEXIST);

	value = s2;
	xbpf_map_update_elem(mapfd, &key, &value, BPF_EXIST);
	xclose(s2);
close_s1:
	xclose(s1);
}

/* Exercise the code path where we destroy child sockets that never
 * got accept()'ed, aka orphans, when parent socket gets closed.
 */
static void do_destroy_orphan_child(int family, int sotype, int mapfd)
{
	struct sockaddr_storage addr;
	socklen_t len;
	int err, s, c;
	u64 value;
	u32 key;

	s = socket_loopback(family, sotype);
	if (s < 0)
		return;

	len = sizeof(addr);
	err = xgetsockname(s, sockaddr(&addr), &len);
	if (err)
		goto close_srv;

	key = 0;
	value = s;
	xbpf_map_update_elem(mapfd, &key, &value, BPF_NOEXIST);

	c = xsocket(family, sotype, 0);
	if (c == -1)
		goto close_srv;

	xconnect(c, sockaddr(&addr), len);
	xclose(c);
close_srv:
	xclose(s);
}

static void test_destroy_orphan_child(struct test_sockmap_listen *skel,
				      int family, int sotype, int mapfd)
{
	int msg_verdict = bpf_program__fd(skel->progs.prog_msg_verdict);
	int skb_verdict = bpf_program__fd(skel->progs.prog_skb_verdict);
	const struct test {
		int progfd;
		enum bpf_attach_type atype;
	} tests[] = {
		{ -1, -1 },
		{ msg_verdict, BPF_SK_MSG_VERDICT },
		{ skb_verdict, BPF_SK_SKB_VERDICT },
	};
	const struct test *t;

	for (t = tests; t < tests + ARRAY_SIZE(tests); t++) {
		if (t->progfd != -1 &&
		    xbpf_prog_attach(t->progfd, mapfd, t->atype, 0) != 0)
			return;

		do_destroy_orphan_child(family, sotype, mapfd);

		if (t->progfd != -1)
			xbpf_prog_detach2(t->progfd, mapfd, t->atype);
	}
}

/* Perform a passive open after removing listening socket from SOCKMAP
 * to ensure that callbacks get restored properly.
 */
static void test_clone_after_delete(struct test_sockmap_listen *skel __always_unused,
				    int family, int sotype, int mapfd)
{
	struct sockaddr_storage addr;
	socklen_t len;
	int err, s, c;
	u64 value;
	u32 key;

	s = socket_loopback(family, sotype);
	if (s < 0)
		return;

	len = sizeof(addr);
	err = xgetsockname(s, sockaddr(&addr), &len);
	if (err)
		goto close_srv;

	key = 0;
	value = s;
	xbpf_map_update_elem(mapfd, &key, &value, BPF_NOEXIST);
	xbpf_map_delete_elem(mapfd, &key);

	c = xsocket(family, sotype, 0);
	if (c < 0)
		goto close_srv;

	xconnect(c, sockaddr(&addr), len);
	xclose(c);
close_srv:
	xclose(s);
}

/* Check that child socket that got created while parent was in a
 * SOCKMAP, but got accept()'ed only after the parent has been removed
 * from SOCKMAP, gets cloned without parent psock state or callbacks.
 */
static void test_accept_after_delete(struct test_sockmap_listen *skel __always_unused,
				     int family, int sotype, int mapfd)
{
	struct sockaddr_storage addr;
	const u32 zero = 0;
	int err, s, c, p;
	socklen_t len;
	u64 value;

	s = socket_loopback(family, sotype | SOCK_NONBLOCK);
	if (s == -1)
		return;

	len = sizeof(addr);
	err = xgetsockname(s, sockaddr(&addr), &len);
	if (err)
		goto close_srv;

	value = s;
	err = xbpf_map_update_elem(mapfd, &zero, &value, BPF_NOEXIST);
	if (err)
		goto close_srv;

	c = xsocket(family, sotype, 0);
	if (c == -1)
		goto close_srv;

	/* Create child while parent is in sockmap */
	err = xconnect(c, sockaddr(&addr), len);
	if (err)
		goto close_cli;

	/* Remove parent from sockmap */
	err = xbpf_map_delete_elem(mapfd, &zero);
	if (err)
		goto close_cli;

	p = xaccept_nonblock(s, NULL, NULL);
	if (p == -1)
		goto close_cli;

	/* Check that child sk_user_data is not set */
	value = p;
	xbpf_map_update_elem(mapfd, &zero, &value, BPF_NOEXIST);

	xclose(p);
close_cli:
	xclose(c);
close_srv:
	xclose(s);
}

/* Check that child socket that got created and accepted while parent
 * was in a SOCKMAP is cloned without parent psock state or callbacks.
 */
static void test_accept_before_delete(struct test_sockmap_listen *skel __always_unused,
				      int family, int sotype, int mapfd)
{
	struct sockaddr_storage addr;
	const u32 zero = 0, one = 1;
	int err, s, c, p;
	socklen_t len;
	u64 value;

	s = socket_loopback(family, sotype | SOCK_NONBLOCK);
	if (s == -1)
		return;

	len = sizeof(addr);
	err = xgetsockname(s, sockaddr(&addr), &len);
	if (err)
		goto close_srv;

	value = s;
	err = xbpf_map_update_elem(mapfd, &zero, &value, BPF_NOEXIST);
	if (err)
		goto close_srv;

	c = xsocket(family, sotype, 0);
	if (c == -1)
		goto close_srv;

	/* Create & accept child while parent is in sockmap */
	err = xconnect(c, sockaddr(&addr), len);
	if (err)
		goto close_cli;

	p = xaccept_nonblock(s, NULL, NULL);
	if (p == -1)
		goto close_cli;

	/* Check that child sk_user_data is not set */
	value = p;
	xbpf_map_update_elem(mapfd, &one, &value, BPF_NOEXIST);

	xclose(p);
close_cli:
	xclose(c);
close_srv:
	xclose(s);
}

struct connect_accept_ctx {
	int sockfd;
	unsigned int done;
	unsigned int nr_iter;
};

static bool is_thread_done(struct connect_accept_ctx *ctx)
{
	return READ_ONCE(ctx->done);
}

static void *connect_accept_thread(void *arg)
{
	struct connect_accept_ctx *ctx = arg;
	struct sockaddr_storage addr;
	int family, socktype;
	socklen_t len;
	int err, i, s;

	s = ctx->sockfd;

	len = sizeof(addr);
	err = xgetsockname(s, sockaddr(&addr), &len);
	if (err)
		goto done;

	len = sizeof(family);
	err = xgetsockopt(s, SOL_SOCKET, SO_DOMAIN, &family, &len);
	if (err)
		goto done;

	len = sizeof(socktype);
	err = xgetsockopt(s, SOL_SOCKET, SO_TYPE, &socktype, &len);
	if (err)
		goto done;

	for (i = 0; i < ctx->nr_iter; i++) {
		int c, p;

		c = xsocket(family, socktype, 0);
		if (c < 0)
			break;

		err = xconnect(c, (struct sockaddr *)&addr, sizeof(addr));
		if (err) {
			xclose(c);
			break;
		}

		p = xaccept_nonblock(s, NULL, NULL);
		if (p < 0) {
			xclose(c);
			break;
		}

		xclose(p);
		xclose(c);
	}
done:
	WRITE_ONCE(ctx->done, 1);
	return NULL;
}

static void test_syn_recv_insert_delete(struct test_sockmap_listen *skel __always_unused,
					int family, int sotype, int mapfd)
{
	struct connect_accept_ctx ctx = { 0 };
	struct sockaddr_storage addr;
	socklen_t len;
	u32 zero = 0;
	pthread_t t;
	int err, s;
	u64 value;

	s = socket_loopback(family, sotype | SOCK_NONBLOCK);
	if (s < 0)
		return;

	len = sizeof(addr);
	err = xgetsockname(s, sockaddr(&addr), &len);
	if (err)
		goto close;

	ctx.sockfd = s;
	ctx.nr_iter = 1000;

	err = xpthread_create(&t, NULL, connect_accept_thread, &ctx);
	if (err)
		goto close;

	value = s;
	while (!is_thread_done(&ctx)) {
		err = xbpf_map_update_elem(mapfd, &zero, &value, BPF_NOEXIST);
		if (err)
			break;

		err = xbpf_map_delete_elem(mapfd, &zero);
		if (err)
			break;
	}

	xpthread_join(t, NULL);
close:
	xclose(s);
}

static void *listen_thread(void *arg)
{
	struct sockaddr unspec = { AF_UNSPEC };
	struct connect_accept_ctx *ctx = arg;
	int err, i, s;

	s = ctx->sockfd;

	for (i = 0; i < ctx->nr_iter; i++) {
		err = xlisten(s, 1);
		if (err)
			break;
		err = xconnect(s, &unspec, sizeof(unspec));
		if (err)
			break;
	}

	WRITE_ONCE(ctx->done, 1);
	return NULL;
}

static void test_race_insert_listen(struct test_sockmap_listen *skel __always_unused,
				    int family, int socktype, int mapfd)
{
	struct connect_accept_ctx ctx = { 0 };
	const u32 zero = 0;
	const int one = 1;
	pthread_t t;
	int err, s;
	u64 value;

	s = xsocket(family, socktype, 0);
	if (s < 0)
		return;

	err = xsetsockopt(s, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
	if (err)
		goto close;

	ctx.sockfd = s;
	ctx.nr_iter = 10000;

	err = pthread_create(&t, NULL, listen_thread, &ctx);
	if (err)
		goto close;

	value = s;
	while (!is_thread_done(&ctx)) {
		err = bpf_map_update_elem(mapfd, &zero, &value, BPF_NOEXIST);
		/* Expecting EOPNOTSUPP before listen() */
		if (err && errno != EOPNOTSUPP) {
			FAIL_ERRNO("map_update");
			break;
		}

		err = bpf_map_delete_elem(mapfd, &zero);
		/* Expecting no entry after unhash on connect(AF_UNSPEC) */
		if (err && errno != EINVAL && errno != ENOENT) {
			FAIL_ERRNO("map_delete");
			break;
		}
	}

	xpthread_join(t, NULL);
close:
	xclose(s);
}

static void zero_verdict_count(int mapfd)
{
	unsigned int zero = 0;
	int key;

	key = SK_DROP;
	xbpf_map_update_elem(mapfd, &key, &zero, BPF_ANY);
	key = SK_PASS;
	xbpf_map_update_elem(mapfd, &key, &zero, BPF_ANY);
}

enum redir_mode {
	REDIR_INGRESS,
	REDIR_EGRESS,
};

static const char *redir_mode_str(enum redir_mode mode)
{
	switch (mode) {
	case REDIR_INGRESS:
		return "ingress";
	case REDIR_EGRESS:
		return "egress";
	default:
		return "unknown";
	}
}

static void redir_to_connected(int family, int sotype, int sock_mapfd,
			       int verd_mapfd, enum redir_mode mode)
{
	const char *log_prefix = redir_mode_str(mode);
	int s, c0, c1, p0, p1;
	unsigned int pass;
	int err, n;
	u32 key;
	char b;

	zero_verdict_count(verd_mapfd);

	s = socket_loopback(family, sotype | SOCK_NONBLOCK);
	if (s < 0)
		return;

	err = create_socket_pairs(s, family, sotype, &c0, &c1, &p0, &p1);
	if (err)
		goto close_srv;

	err = add_to_sockmap(sock_mapfd, p0, p1);
	if (err)
		goto close;

	n = write(mode == REDIR_INGRESS ? c1 : p1, "a", 1);
	if (n < 0)
		FAIL_ERRNO("%s: write", log_prefix);
	if (n == 0)
		FAIL("%s: incomplete write", log_prefix);
	if (n < 1)
		goto close;

	key = SK_PASS;
	err = xbpf_map_lookup_elem(verd_mapfd, &key, &pass);
	if (err)
		goto close;
	if (pass != 1)
		FAIL("%s: want pass count 1, have %d", log_prefix, pass);
	n = recv_timeout(c0, &b, 1, 0, IO_TIMEOUT_SEC);
	if (n < 0)
		FAIL_ERRNO("%s: recv_timeout", log_prefix);
	if (n == 0)
		FAIL("%s: incomplete recv", log_prefix);

close:
	xclose(p1);
	xclose(c1);
	xclose(p0);
	xclose(c0);
close_srv:
	xclose(s);
}

static void test_skb_redir_to_connected(struct test_sockmap_listen *skel,
					struct bpf_map *inner_map, int family,
					int sotype)
{
	int verdict = bpf_program__fd(skel->progs.prog_stream_verdict);
	int parser = bpf_program__fd(skel->progs.prog_stream_parser);
	int verdict_map = bpf_map__fd(skel->maps.verdict_map);
	int sock_map = bpf_map__fd(inner_map);
	int err;

	err = xbpf_prog_attach(parser, sock_map, BPF_SK_SKB_STREAM_PARSER, 0);
	if (err)
		return;
	err = xbpf_prog_attach(verdict, sock_map, BPF_SK_SKB_STREAM_VERDICT, 0);
	if (err)
		goto detach;

	redir_to_connected(family, sotype, sock_map, verdict_map,
			   REDIR_INGRESS);

	xbpf_prog_detach2(verdict, sock_map, BPF_SK_SKB_STREAM_VERDICT);
detach:
	xbpf_prog_detach2(parser, sock_map, BPF_SK_SKB_STREAM_PARSER);
}

static void test_msg_redir_to_connected(struct test_sockmap_listen *skel,
					struct bpf_map *inner_map, int family,
					int sotype)
{
	int verdict = bpf_program__fd(skel->progs.prog_msg_verdict);
	int verdict_map = bpf_map__fd(skel->maps.verdict_map);
	int sock_map = bpf_map__fd(inner_map);
	int err;

	err = xbpf_prog_attach(verdict, sock_map, BPF_SK_MSG_VERDICT, 0);
	if (err)
		return;

	redir_to_connected(family, sotype, sock_map, verdict_map, REDIR_EGRESS);

	xbpf_prog_detach2(verdict, sock_map, BPF_SK_MSG_VERDICT);
}

static void redir_to_listening(int family, int sotype, int sock_mapfd,
			       int verd_mapfd, enum redir_mode mode)
{
	const char *log_prefix = redir_mode_str(mode);
	struct sockaddr_storage addr;
	int s, c, p, err, n;
	unsigned int drop;
	socklen_t len;
	u32 key;

	zero_verdict_count(verd_mapfd);

	s = socket_loopback(family, sotype | SOCK_NONBLOCK);
	if (s < 0)
		return;

	len = sizeof(addr);
	err = xgetsockname(s, sockaddr(&addr), &len);
	if (err)
		goto close_srv;

	c = xsocket(family, sotype, 0);
	if (c < 0)
		goto close_srv;
	err = xconnect(c, sockaddr(&addr), len);
	if (err)
		goto close_cli;

	p = xaccept_nonblock(s, NULL, NULL);
	if (p < 0)
		goto close_cli;

	err = add_to_sockmap(sock_mapfd, s, p);
	if (err)
		goto close_peer;

	n = write(mode == REDIR_INGRESS ? c : p, "a", 1);
	if (n < 0 && errno != EACCES)
		FAIL_ERRNO("%s: write", log_prefix);
	if (n == 0)
		FAIL("%s: incomplete write", log_prefix);
	if (n < 1)
		goto close_peer;

	key = SK_DROP;
	err = xbpf_map_lookup_elem(verd_mapfd, &key, &drop);
	if (err)
		goto close_peer;
	if (drop != 1)
		FAIL("%s: want drop count 1, have %d", log_prefix, drop);

close_peer:
	xclose(p);
close_cli:
	xclose(c);
close_srv:
	xclose(s);
}

static void test_skb_redir_to_listening(struct test_sockmap_listen *skel,
					struct bpf_map *inner_map, int family,
					int sotype)
{
	int verdict = bpf_program__fd(skel->progs.prog_stream_verdict);
	int parser = bpf_program__fd(skel->progs.prog_stream_parser);
	int verdict_map = bpf_map__fd(skel->maps.verdict_map);
	int sock_map = bpf_map__fd(inner_map);
	int err;

	err = xbpf_prog_attach(parser, sock_map, BPF_SK_SKB_STREAM_PARSER, 0);
	if (err)
		return;
	err = xbpf_prog_attach(verdict, sock_map, BPF_SK_SKB_STREAM_VERDICT, 0);
	if (err)
		goto detach;

	redir_to_listening(family, sotype, sock_map, verdict_map,
			   REDIR_INGRESS);

	xbpf_prog_detach2(verdict, sock_map, BPF_SK_SKB_STREAM_VERDICT);
detach:
	xbpf_prog_detach2(parser, sock_map, BPF_SK_SKB_STREAM_PARSER);
}

static void test_msg_redir_to_listening(struct test_sockmap_listen *skel,
					struct bpf_map *inner_map, int family,
					int sotype)
{
	int verdict = bpf_program__fd(skel->progs.prog_msg_verdict);
	int verdict_map = bpf_map__fd(skel->maps.verdict_map);
	int sock_map = bpf_map__fd(inner_map);
	int err;

	err = xbpf_prog_attach(verdict, sock_map, BPF_SK_MSG_VERDICT, 0);
	if (err)
		return;

	redir_to_listening(family, sotype, sock_map, verdict_map, REDIR_EGRESS);

	xbpf_prog_detach2(verdict, sock_map, BPF_SK_MSG_VERDICT);
}

static void redir_partial(int family, int sotype, int sock_map, int parser_map)
{
	int s, c0 = -1, c1 = -1, p0 = -1, p1 = -1;
	int err, n, key, value;
	char buf[] = "abc";

	key = 0;
	value = sizeof(buf) - 1;
	err = xbpf_map_update_elem(parser_map, &key, &value, 0);
	if (err)
		return;

	s = socket_loopback(family, sotype | SOCK_NONBLOCK);
	if (s < 0)
		goto clean_parser_map;

	err = create_socket_pairs(s, family, sotype, &c0, &c1, &p0, &p1);
	if (err)
		goto close_srv;

	err = add_to_sockmap(sock_map, p0, p1);
	if (err)
		goto close;

	n = xsend(c1, buf, sizeof(buf), 0);
	if (n < sizeof(buf))
		FAIL("incomplete write");

	n = xrecv_nonblock(c0, buf, sizeof(buf), 0);
	if (n != sizeof(buf) - 1)
		FAIL("expect %zu, received %d", sizeof(buf) - 1, n);

close:
	xclose(c0);
	xclose(p0);
	xclose(c1);
	xclose(p1);
close_srv:
	xclose(s);

clean_parser_map:
	key = 0;
	value = 0;
	xbpf_map_update_elem(parser_map, &key, &value, 0);
}

static void test_skb_redir_partial(struct test_sockmap_listen *skel,
				   struct bpf_map *inner_map, int family,
				   int sotype)
{
	int verdict = bpf_program__fd(skel->progs.prog_stream_verdict);
	int parser = bpf_program__fd(skel->progs.prog_stream_parser);
	int parser_map = bpf_map__fd(skel->maps.parser_map);
	int sock_map = bpf_map__fd(inner_map);
	int err;

	err = xbpf_prog_attach(parser, sock_map, BPF_SK_SKB_STREAM_PARSER, 0);
	if (err)
		return;

	err = xbpf_prog_attach(verdict, sock_map, BPF_SK_SKB_STREAM_VERDICT, 0);
	if (err)
		goto detach;

	redir_partial(family, sotype, sock_map, parser_map);

	xbpf_prog_detach2(verdict, sock_map, BPF_SK_SKB_STREAM_VERDICT);
detach:
	xbpf_prog_detach2(parser, sock_map, BPF_SK_SKB_STREAM_PARSER);
}

static void test_reuseport_select_listening(int family, int sotype,
					    int sock_map, int verd_map,
					    int reuseport_prog)
{
	struct sockaddr_storage addr;
	unsigned int pass;
	int s, c, err;
	socklen_t len;
	u64 value;
	u32 key;

	zero_verdict_count(verd_map);

	s = socket_loopback_reuseport(family, sotype | SOCK_NONBLOCK,
				      reuseport_prog);
	if (s < 0)
		return;

	len = sizeof(addr);
	err = xgetsockname(s, sockaddr(&addr), &len);
	if (err)
		goto close_srv;

	key = 0;
	value = s;
	err = xbpf_map_update_elem(sock_map, &key, &value, BPF_NOEXIST);
	if (err)
		goto close_srv;

	c = xsocket(family, sotype, 0);
	if (c < 0)
		goto close_srv;
	err = xconnect(c, sockaddr(&addr), len);
	if (err)
		goto close_cli;

	if (sotype == SOCK_STREAM) {
		int p;

		p = xaccept_nonblock(s, NULL, NULL);
		if (p < 0)
			goto close_cli;
		xclose(p);
	} else {
		char b = 'a';
		ssize_t n;

		n = xsend(c, &b, sizeof(b), 0);
		if (n == -1)
			goto close_cli;

		n = xrecv_nonblock(s, &b, sizeof(b), 0);
		if (n == -1)
			goto close_cli;
	}

	key = SK_PASS;
	err = xbpf_map_lookup_elem(verd_map, &key, &pass);
	if (err)
		goto close_cli;
	if (pass != 1)
		FAIL("want pass count 1, have %d", pass);

close_cli:
	xclose(c);
close_srv:
	xclose(s);
}

static void test_reuseport_select_connected(int family, int sotype,
					    int sock_map, int verd_map,
					    int reuseport_prog)
{
	struct sockaddr_storage addr;
	int s, c0, c1, p0, err;
	unsigned int drop;
	socklen_t len;
	u64 value;
	u32 key;

	zero_verdict_count(verd_map);

	s = socket_loopback_reuseport(family, sotype, reuseport_prog);
	if (s < 0)
		return;

	/* Populate sock_map[0] to avoid ENOENT on first connection */
	key = 0;
	value = s;
	err = xbpf_map_update_elem(sock_map, &key, &value, BPF_NOEXIST);
	if (err)
		goto close_srv;

	len = sizeof(addr);
	err = xgetsockname(s, sockaddr(&addr), &len);
	if (err)
		goto close_srv;

	c0 = xsocket(family, sotype, 0);
	if (c0 < 0)
		goto close_srv;

	err = xconnect(c0, sockaddr(&addr), len);
	if (err)
		goto close_cli0;

	if (sotype == SOCK_STREAM) {
		p0 = xaccept_nonblock(s, NULL, NULL);
		if (p0 < 0)
			goto close_cli0;
	} else {
		p0 = xsocket(family, sotype, 0);
		if (p0 < 0)
			goto close_cli0;

		len = sizeof(addr);
		err = xgetsockname(c0, sockaddr(&addr), &len);
		if (err)
			goto close_cli0;

		err = xconnect(p0, sockaddr(&addr), len);
		if (err)
			goto close_cli0;
	}

	/* Update sock_map[0] to redirect to a connected socket */
	key = 0;
	value = p0;
	err = xbpf_map_update_elem(sock_map, &key, &value, BPF_EXIST);
	if (err)
		goto close_peer0;

	c1 = xsocket(family, sotype, 0);
	if (c1 < 0)
		goto close_peer0;

	len = sizeof(addr);
	err = xgetsockname(s, sockaddr(&addr), &len);
	if (err)
		goto close_srv;

	errno = 0;
	err = connect(c1, sockaddr(&addr), len);
	if (sotype == SOCK_DGRAM) {
		char b = 'a';
		ssize_t n;

		n = xsend(c1, &b, sizeof(b), 0);
		if (n == -1)
			goto close_cli1;

		n = recv_timeout(c1, &b, sizeof(b), 0, IO_TIMEOUT_SEC);
		err = n == -1;
	}
	if (!err || errno != ECONNREFUSED)
		FAIL_ERRNO("connect: expected ECONNREFUSED");

	key = SK_DROP;
	err = xbpf_map_lookup_elem(verd_map, &key, &drop);
	if (err)
		goto close_cli1;
	if (drop != 1)
		FAIL("want drop count 1, have %d", drop);

close_cli1:
	xclose(c1);
close_peer0:
	xclose(p0);
close_cli0:
	xclose(c0);
close_srv:
	xclose(s);
}

/* Check that redirecting across reuseport groups is not allowed. */
static void test_reuseport_mixed_groups(int family, int sotype, int sock_map,
					int verd_map, int reuseport_prog)
{
	struct sockaddr_storage addr;
	int s1, s2, c, err;
	unsigned int drop;
	socklen_t len;
	u32 key;

	zero_verdict_count(verd_map);

	/* Create two listeners, each in its own reuseport group */
	s1 = socket_loopback_reuseport(family, sotype, reuseport_prog);
	if (s1 < 0)
		return;

	s2 = socket_loopback_reuseport(family, sotype, reuseport_prog);
	if (s2 < 0)
		goto close_srv1;

	err = add_to_sockmap(sock_map, s1, s2);
	if (err)
		goto close_srv2;

	/* Connect to s2, reuseport BPF selects s1 via sock_map[0] */
	len = sizeof(addr);
	err = xgetsockname(s2, sockaddr(&addr), &len);
	if (err)
		goto close_srv2;

	c = xsocket(family, sotype, 0);
	if (c < 0)
		goto close_srv2;

	err = connect(c, sockaddr(&addr), len);
	if (sotype == SOCK_DGRAM) {
		char b = 'a';
		ssize_t n;

		n = xsend(c, &b, sizeof(b), 0);
		if (n == -1)
			goto close_cli;

		n = recv_timeout(c, &b, sizeof(b), 0, IO_TIMEOUT_SEC);
		err = n == -1;
	}
	if (!err || errno != ECONNREFUSED) {
		FAIL_ERRNO("connect: expected ECONNREFUSED");
		goto close_cli;
	}

	/* Expect drop, can't redirect outside of reuseport group */
	key = SK_DROP;
	err = xbpf_map_lookup_elem(verd_map, &key, &drop);
	if (err)
		goto close_cli;
	if (drop != 1)
		FAIL("want drop count 1, have %d", drop);

close_cli:
	xclose(c);
close_srv2:
	xclose(s2);
close_srv1:
	xclose(s1);
}

#define TEST(fn, ...)                                                          \
	{                                                                      \
		fn, #fn, __VA_ARGS__                                           \
	}

static void test_ops_cleanup(const struct bpf_map *map)
{
	int err, mapfd;
	u32 key;

	mapfd = bpf_map__fd(map);

	for (key = 0; key < bpf_map__max_entries(map); key++) {
		err = bpf_map_delete_elem(mapfd, &key);
		if (err && errno != EINVAL && errno != ENOENT)
			FAIL_ERRNO("map_delete: expected EINVAL/ENOENT");
	}
}

static const char *family_str(sa_family_t family)
{
	switch (family) {
	case AF_INET:
		return "IPv4";
	case AF_INET6:
		return "IPv6";
	case AF_UNIX:
		return "Unix";
	case AF_VSOCK:
		return "VSOCK";
	default:
		return "unknown";
	}
}

static const char *map_type_str(const struct bpf_map *map)
{
	int type;

	if (!map)
		return "invalid";
	type = bpf_map__type(map);

	switch (type) {
	case BPF_MAP_TYPE_SOCKMAP:
		return "sockmap";
	case BPF_MAP_TYPE_SOCKHASH:
		return "sockhash";
	default:
		return "unknown";
	}
}

static const char *sotype_str(int sotype)
{
	switch (sotype) {
	case SOCK_DGRAM:
		return "UDP";
	case SOCK_STREAM:
		return "TCP";
	default:
		return "unknown";
	}
}

static void test_ops(struct test_sockmap_listen *skel, struct bpf_map *map,
		     int family, int sotype)
{
	const struct op_test {
		void (*fn)(struct test_sockmap_listen *skel,
			   int family, int sotype, int mapfd);
		const char *name;
		int sotype;
	} tests[] = {
		/* insert */
		TEST(test_insert_invalid),
		TEST(test_insert_opened),
		TEST(test_insert_bound, SOCK_STREAM),
		TEST(test_insert),
		/* delete */
		TEST(test_delete_after_insert),
		TEST(test_delete_after_close),
		/* lookup */
		TEST(test_lookup_after_insert),
		TEST(test_lookup_after_delete),
		TEST(test_lookup_32_bit_value),
		/* update */
		TEST(test_update_existing),
		/* races with insert/delete */
		TEST(test_destroy_orphan_child, SOCK_STREAM),
		TEST(test_syn_recv_insert_delete, SOCK_STREAM),
		TEST(test_race_insert_listen, SOCK_STREAM),
		/* child clone */
		TEST(test_clone_after_delete, SOCK_STREAM),
		TEST(test_accept_after_delete, SOCK_STREAM),
		TEST(test_accept_before_delete, SOCK_STREAM),
	};
	const char *family_name, *map_name, *sotype_name;
	const struct op_test *t;
	char s[MAX_TEST_NAME];
	int map_fd;

	family_name = family_str(family);
	map_name = map_type_str(map);
	sotype_name = sotype_str(sotype);
	map_fd = bpf_map__fd(map);

	for (t = tests; t < tests + ARRAY_SIZE(tests); t++) {
		snprintf(s, sizeof(s), "%s %s %s %s", map_name, family_name,
			 sotype_name, t->name);

		if (t->sotype != 0 && t->sotype != sotype)
			continue;

		if (!test__start_subtest(s))
			continue;

		t->fn(skel, family, sotype, map_fd);
		test_ops_cleanup(map);
	}
}

static void test_redir(struct test_sockmap_listen *skel, struct bpf_map *map,
		       int family, int sotype)
{
	const struct redir_test {
		void (*fn)(struct test_sockmap_listen *skel,
			   struct bpf_map *map, int family, int sotype);
		const char *name;
	} tests[] = {
		TEST(test_skb_redir_to_connected),
		TEST(test_skb_redir_to_listening),
		TEST(test_skb_redir_partial),
		TEST(test_msg_redir_to_connected),
		TEST(test_msg_redir_to_listening),
	};
	const char *family_name, *map_name;
	const struct redir_test *t;
	char s[MAX_TEST_NAME];

	family_name = family_str(family);
	map_name = map_type_str(map);

	for (t = tests; t < tests + ARRAY_SIZE(tests); t++) {
		snprintf(s, sizeof(s), "%s %s %s", map_name, family_name,
			 t->name);

		if (!test__start_subtest(s))
			continue;

		t->fn(skel, map, family, sotype);
	}
}

static void pairs_redir_to_connected(int cli0, int peer0, int cli1, int peer1,
				     int sock_mapfd, int nop_mapfd,
				     int verd_mapfd, enum redir_mode mode)
{
	const char *log_prefix = redir_mode_str(mode);
	unsigned int pass;
	int err, n;
	u32 key;
	char b;

	zero_verdict_count(verd_mapfd);

	err = add_to_sockmap(sock_mapfd, peer0, peer1);
	if (err)
		return;

	if (nop_mapfd >= 0) {
		err = add_to_sockmap(nop_mapfd, cli0, cli1);
		if (err)
			return;
	}

	n = write(cli1, "a", 1);
	if (n < 0)
		FAIL_ERRNO("%s: write", log_prefix);
	if (n == 0)
		FAIL("%s: incomplete write", log_prefix);
	if (n < 1)
		return;

	key = SK_PASS;
	err = xbpf_map_lookup_elem(verd_mapfd, &key, &pass);
	if (err)
		return;
	if (pass != 1)
		FAIL("%s: want pass count 1, have %d", log_prefix, pass);

	n = recv_timeout(mode == REDIR_INGRESS ? peer0 : cli0, &b, 1, 0, IO_TIMEOUT_SEC);
	if (n < 0)
		FAIL_ERRNO("%s: recv_timeout", log_prefix);
	if (n == 0)
		FAIL("%s: incomplete recv", log_prefix);
}

static void unix_redir_to_connected(int sotype, int sock_mapfd,
			       int verd_mapfd, enum redir_mode mode)
{
	int c0, c1, p0, p1;
	int sfd[2];

	if (socketpair(AF_UNIX, sotype | SOCK_NONBLOCK, 0, sfd))
		return;
	c0 = sfd[0], p0 = sfd[1];

	if (socketpair(AF_UNIX, sotype | SOCK_NONBLOCK, 0, sfd))
		goto close0;
	c1 = sfd[0], p1 = sfd[1];

	pairs_redir_to_connected(c0, p0, c1, p1, sock_mapfd, -1, verd_mapfd, mode);

	xclose(c1);
	xclose(p1);
close0:
	xclose(c0);
	xclose(p0);
}

static void unix_skb_redir_to_connected(struct test_sockmap_listen *skel,
					struct bpf_map *inner_map, int sotype)
{
	int verdict = bpf_program__fd(skel->progs.prog_skb_verdict);
	int verdict_map = bpf_map__fd(skel->maps.verdict_map);
	int sock_map = bpf_map__fd(inner_map);
	int err;

	err = xbpf_prog_attach(verdict, sock_map, BPF_SK_SKB_VERDICT, 0);
	if (err)
		return;

	skel->bss->test_ingress = false;
	unix_redir_to_connected(sotype, sock_map, verdict_map, REDIR_EGRESS);
	skel->bss->test_ingress = true;
	unix_redir_to_connected(sotype, sock_map, verdict_map, REDIR_INGRESS);

	xbpf_prog_detach2(verdict, sock_map, BPF_SK_SKB_VERDICT);
}

static void test_unix_redir(struct test_sockmap_listen *skel, struct bpf_map *map,
			    int sotype)
{
	const char *family_name, *map_name;
	char s[MAX_TEST_NAME];

	family_name = family_str(AF_UNIX);
	map_name = map_type_str(map);
	snprintf(s, sizeof(s), "%s %s %s", map_name, family_name, __func__);
	if (!test__start_subtest(s))
		return;
	unix_skb_redir_to_connected(skel, map, sotype);
}

/* Returns two connected loopback vsock sockets */
static int vsock_socketpair_connectible(int sotype, int *v0, int *v1)
{
	struct sockaddr_storage addr;
	socklen_t len = sizeof(addr);
	int s, p, c;

	s = socket_loopback(AF_VSOCK, sotype);
	if (s < 0)
		return -1;

	c = xsocket(AF_VSOCK, sotype | SOCK_NONBLOCK, 0);
	if (c == -1)
		goto close_srv;

	if (getsockname(s, sockaddr(&addr), &len) < 0)
		goto close_cli;

	if (connect(c, sockaddr(&addr), len) < 0 && errno != EINPROGRESS) {
		FAIL_ERRNO("connect");
		goto close_cli;
	}

	len = sizeof(addr);
	p = accept_timeout(s, sockaddr(&addr), &len, IO_TIMEOUT_SEC);
	if (p < 0)
		goto close_cli;

	if (poll_connect(c, IO_TIMEOUT_SEC) < 0) {
		FAIL_ERRNO("poll_connect");
		goto close_acc;
	}

	*v0 = p;
	*v1 = c;

	return 0;

close_acc:
	close(p);
close_cli:
	close(c);
close_srv:
	close(s);

	return -1;
}

static void vsock_unix_redir_connectible(int sock_mapfd, int verd_mapfd,
					 enum redir_mode mode, int sotype)
{
	const char *log_prefix = redir_mode_str(mode);
	char a = 'a', b = 'b';
	int u0, u1, v0, v1;
	int sfd[2];
	unsigned int pass;
	int err, n;
	u32 key;

	zero_verdict_count(verd_mapfd);

	if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK, 0, sfd))
		return;

	u0 = sfd[0];
	u1 = sfd[1];

	err = vsock_socketpair_connectible(sotype, &v0, &v1);
	if (err) {
		FAIL("vsock_socketpair_connectible() failed");
		goto close_uds;
	}

	err = add_to_sockmap(sock_mapfd, u0, v0);
	if (err) {
		FAIL("add_to_sockmap failed");
		goto close_vsock;
	}

	n = write(v1, &a, sizeof(a));
	if (n < 0)
		FAIL_ERRNO("%s: write", log_prefix);
	if (n == 0)
		FAIL("%s: incomplete write", log_prefix);
	if (n < 1)
		goto out;

	n = xrecv_nonblock(mode == REDIR_INGRESS ? u0 : u1, &b, sizeof(b), 0);
	if (n < 0)
		FAIL("%s: recv() err, errno=%d", log_prefix, errno);
	if (n == 0)
		FAIL("%s: incomplete recv", log_prefix);
	if (b != a)
		FAIL("%s: vsock socket map failed, %c != %c", log_prefix, a, b);

	key = SK_PASS;
	err = xbpf_map_lookup_elem(verd_mapfd, &key, &pass);
	if (err)
		goto out;
	if (pass != 1)
		FAIL("%s: want pass count 1, have %d", log_prefix, pass);
out:
	key = 0;
	bpf_map_delete_elem(sock_mapfd, &key);
	key = 1;
	bpf_map_delete_elem(sock_mapfd, &key);

close_vsock:
	close(v0);
	close(v1);

close_uds:
	close(u0);
	close(u1);
}

static void vsock_unix_skb_redir_connectible(struct test_sockmap_listen *skel,
					     struct bpf_map *inner_map,
					     int sotype)
{
	int verdict = bpf_program__fd(skel->progs.prog_skb_verdict);
	int verdict_map = bpf_map__fd(skel->maps.verdict_map);
	int sock_map = bpf_map__fd(inner_map);
	int err;

	err = xbpf_prog_attach(verdict, sock_map, BPF_SK_SKB_VERDICT, 0);
	if (err)
		return;

	skel->bss->test_ingress = false;
	vsock_unix_redir_connectible(sock_map, verdict_map, REDIR_EGRESS, sotype);
	skel->bss->test_ingress = true;
	vsock_unix_redir_connectible(sock_map, verdict_map, REDIR_INGRESS, sotype);

	xbpf_prog_detach2(verdict, sock_map, BPF_SK_SKB_VERDICT);
}

static void test_vsock_redir(struct test_sockmap_listen *skel, struct bpf_map *map)
{
	const char *family_name, *map_name;
	char s[MAX_TEST_NAME];

	family_name = family_str(AF_VSOCK);
	map_name = map_type_str(map);
	snprintf(s, sizeof(s), "%s %s %s", map_name, family_name, __func__);
	if (!test__start_subtest(s))
		return;

	vsock_unix_skb_redir_connectible(skel, map, SOCK_STREAM);
	vsock_unix_skb_redir_connectible(skel, map, SOCK_SEQPACKET);
}

static void test_reuseport(struct test_sockmap_listen *skel,
			   struct bpf_map *map, int family, int sotype)
{
	const struct reuseport_test {
		void (*fn)(int family, int sotype, int socket_map,
			   int verdict_map, int reuseport_prog);
		const char *name;
		int sotype;
	} tests[] = {
		TEST(test_reuseport_select_listening),
		TEST(test_reuseport_select_connected),
		TEST(test_reuseport_mixed_groups),
	};
	int socket_map, verdict_map, reuseport_prog;
	const char *family_name, *map_name, *sotype_name;
	const struct reuseport_test *t;
	char s[MAX_TEST_NAME];

	family_name = family_str(family);
	map_name = map_type_str(map);
	sotype_name = sotype_str(sotype);

	socket_map = bpf_map__fd(map);
	verdict_map = bpf_map__fd(skel->maps.verdict_map);
	reuseport_prog = bpf_program__fd(skel->progs.prog_reuseport);

	for (t = tests; t < tests + ARRAY_SIZE(tests); t++) {
		snprintf(s, sizeof(s), "%s %s %s %s", map_name, family_name,
			 sotype_name, t->name);

		if (t->sotype != 0 && t->sotype != sotype)
			continue;

		if (!test__start_subtest(s))
			continue;

		t->fn(family, sotype, socket_map, verdict_map, reuseport_prog);
	}
}

static int inet_socketpair(int family, int type, int *s, int *c)
{
	struct sockaddr_storage addr;
	socklen_t len;
	int p0, c0;
	int err;

	p0 = socket_loopback(family, type | SOCK_NONBLOCK);
	if (p0 < 0)
		return p0;

	len = sizeof(addr);
	err = xgetsockname(p0, sockaddr(&addr), &len);
	if (err)
		goto close_peer0;

	c0 = xsocket(family, type | SOCK_NONBLOCK, 0);
	if (c0 < 0) {
		err = c0;
		goto close_peer0;
	}
	err = xconnect(c0, sockaddr(&addr), len);
	if (err)
		goto close_cli0;
	err = xgetsockname(c0, sockaddr(&addr), &len);
	if (err)
		goto close_cli0;
	err = xconnect(p0, sockaddr(&addr), len);
	if (err)
		goto close_cli0;

	*s = p0;
	*c = c0;
	return 0;

close_cli0:
	xclose(c0);
close_peer0:
	xclose(p0);
	return err;
}

static void udp_redir_to_connected(int family, int sock_mapfd, int verd_mapfd,
				   enum redir_mode mode)
{
	int c0, c1, p0, p1;
	int err;

	err = inet_socketpair(family, SOCK_DGRAM, &p0, &c0);
	if (err)
		return;
	err = inet_socketpair(family, SOCK_DGRAM, &p1, &c1);
	if (err)
		goto close_cli0;

	pairs_redir_to_connected(c0, p0, c1, p1, sock_mapfd, -1, verd_mapfd, mode);

	xclose(c1);
	xclose(p1);
close_cli0:
	xclose(c0);
	xclose(p0);
}

static void udp_skb_redir_to_connected(struct test_sockmap_listen *skel,
				       struct bpf_map *inner_map, int family)
{
	int verdict = bpf_program__fd(skel->progs.prog_skb_verdict);
	int verdict_map = bpf_map__fd(skel->maps.verdict_map);
	int sock_map = bpf_map__fd(inner_map);
	int err;

	err = xbpf_prog_attach(verdict, sock_map, BPF_SK_SKB_VERDICT, 0);
	if (err)
		return;

	skel->bss->test_ingress = false;
	udp_redir_to_connected(family, sock_map, verdict_map, REDIR_EGRESS);
	skel->bss->test_ingress = true;
	udp_redir_to_connected(family, sock_map, verdict_map, REDIR_INGRESS);

	xbpf_prog_detach2(verdict, sock_map, BPF_SK_SKB_VERDICT);
}

static void test_udp_redir(struct test_sockmap_listen *skel, struct bpf_map *map,
			   int family)
{
	const char *family_name, *map_name;
	char s[MAX_TEST_NAME];

	family_name = family_str(family);
	map_name = map_type_str(map);
	snprintf(s, sizeof(s), "%s %s %s", map_name, family_name, __func__);
	if (!test__start_subtest(s))
		return;
	udp_skb_redir_to_connected(skel, map, family);
}

static void inet_unix_redir_to_connected(int family, int type, int sock_mapfd,
					int verd_mapfd, enum redir_mode mode)
{
	int c0, c1, p0, p1;
	int sfd[2];
	int err;

	if (socketpair(AF_UNIX, SOCK_DGRAM | SOCK_NONBLOCK, 0, sfd))
		return;
	c0 = sfd[0], p0 = sfd[1];

	err = inet_socketpair(family, SOCK_DGRAM, &p1, &c1);
	if (err)
		goto close;

	pairs_redir_to_connected(c0, p0, c1, p1, sock_mapfd, -1, verd_mapfd, mode);

	xclose(c1);
	xclose(p1);
close:
	xclose(c0);
	xclose(p0);
}

static void inet_unix_skb_redir_to_connected(struct test_sockmap_listen *skel,
					    struct bpf_map *inner_map, int family)
{
	int verdict = bpf_program__fd(skel->progs.prog_skb_verdict);
	int verdict_map = bpf_map__fd(skel->maps.verdict_map);
	int sock_map = bpf_map__fd(inner_map);
	int err;

	err = xbpf_prog_attach(verdict, sock_map, BPF_SK_SKB_VERDICT, 0);
	if (err)
		return;

	skel->bss->test_ingress = false;
	inet_unix_redir_to_connected(family, SOCK_DGRAM, sock_map, verdict_map,
				    REDIR_EGRESS);
	inet_unix_redir_to_connected(family, SOCK_STREAM, sock_map, verdict_map,
				    REDIR_EGRESS);
	skel->bss->test_ingress = true;
	inet_unix_redir_to_connected(family, SOCK_DGRAM, sock_map, verdict_map,
				    REDIR_INGRESS);
	inet_unix_redir_to_connected(family, SOCK_STREAM, sock_map, verdict_map,
				    REDIR_INGRESS);

	xbpf_prog_detach2(verdict, sock_map, BPF_SK_SKB_VERDICT);
}

static void unix_inet_redir_to_connected(int family, int type,
					int sock_mapfd, int nop_mapfd,
					int verd_mapfd,
					enum redir_mode mode)
{
	int c0, c1, p0, p1;
	int sfd[2];
	int err;

	err = inet_socketpair(family, SOCK_DGRAM, &p0, &c0);
	if (err)
		return;

	if (socketpair(AF_UNIX, SOCK_DGRAM | SOCK_NONBLOCK, 0, sfd))
		goto close_cli0;
	c1 = sfd[0], p1 = sfd[1];

	pairs_redir_to_connected(c0, p0, c1, p1,
				 sock_mapfd, nop_mapfd, verd_mapfd, mode);

	xclose(c1);
	xclose(p1);
close_cli0:
	xclose(c0);
	xclose(p0);

}

static void unix_inet_skb_redir_to_connected(struct test_sockmap_listen *skel,
					    struct bpf_map *inner_map, int family)
{
	int verdict = bpf_program__fd(skel->progs.prog_skb_verdict);
	int nop_map = bpf_map__fd(skel->maps.nop_map);
	int verdict_map = bpf_map__fd(skel->maps.verdict_map);
	int sock_map = bpf_map__fd(inner_map);
	int err;

	err = xbpf_prog_attach(verdict, sock_map, BPF_SK_SKB_VERDICT, 0);
	if (err)
		return;

	skel->bss->test_ingress = false;
	unix_inet_redir_to_connected(family, SOCK_DGRAM,
				     sock_map, -1, verdict_map,
				     REDIR_EGRESS);
	unix_inet_redir_to_connected(family, SOCK_DGRAM,
				     sock_map, -1, verdict_map,
				     REDIR_EGRESS);

	unix_inet_redir_to_connected(family, SOCK_DGRAM,
				     sock_map, nop_map, verdict_map,
				     REDIR_EGRESS);
	unix_inet_redir_to_connected(family, SOCK_STREAM,
				     sock_map, nop_map, verdict_map,
				     REDIR_EGRESS);
	skel->bss->test_ingress = true;
	unix_inet_redir_to_connected(family, SOCK_DGRAM,
				     sock_map, -1, verdict_map,
				     REDIR_INGRESS);
	unix_inet_redir_to_connected(family, SOCK_STREAM,
				     sock_map, -1, verdict_map,
				     REDIR_INGRESS);

	unix_inet_redir_to_connected(family, SOCK_DGRAM,
				     sock_map, nop_map, verdict_map,
				     REDIR_INGRESS);
	unix_inet_redir_to_connected(family, SOCK_STREAM,
				     sock_map, nop_map, verdict_map,
				     REDIR_INGRESS);

	xbpf_prog_detach2(verdict, sock_map, BPF_SK_SKB_VERDICT);
}

static void test_udp_unix_redir(struct test_sockmap_listen *skel, struct bpf_map *map,
				int family)
{
	const char *family_name, *map_name;
	char s[MAX_TEST_NAME];

	family_name = family_str(family);
	map_name = map_type_str(map);
	snprintf(s, sizeof(s), "%s %s %s", map_name, family_name, __func__);
	if (!test__start_subtest(s))
		return;
	inet_unix_skb_redir_to_connected(skel, map, family);
	unix_inet_skb_redir_to_connected(skel, map, family);
}

static void run_tests(struct test_sockmap_listen *skel, struct bpf_map *map,
		      int family)
{
	test_ops(skel, map, family, SOCK_STREAM);
	test_ops(skel, map, family, SOCK_DGRAM);
	test_redir(skel, map, family, SOCK_STREAM);
	test_reuseport(skel, map, family, SOCK_STREAM);
	test_reuseport(skel, map, family, SOCK_DGRAM);
	test_udp_redir(skel, map, family);
	test_udp_unix_redir(skel, map, family);
}

void serial_test_sockmap_listen(void)
{
	struct test_sockmap_listen *skel;

	skel = test_sockmap_listen__open_and_load();
	if (!skel) {
		FAIL("skeleton open/load failed");
		return;
	}

	skel->bss->test_sockmap = true;
	run_tests(skel, skel->maps.sock_map, AF_INET);
	run_tests(skel, skel->maps.sock_map, AF_INET6);
	test_unix_redir(skel, skel->maps.sock_map, SOCK_DGRAM);
	test_unix_redir(skel, skel->maps.sock_map, SOCK_STREAM);
	test_vsock_redir(skel, skel->maps.sock_map);

	skel->bss->test_sockmap = false;
	run_tests(skel, skel->maps.sock_hash, AF_INET);
	run_tests(skel, skel->maps.sock_hash, AF_INET6);
	test_unix_redir(skel, skel->maps.sock_hash, SOCK_DGRAM);
	test_unix_redir(skel, skel->maps.sock_hash, SOCK_STREAM);
	test_vsock_redir(skel, skel->maps.sock_hash);

	test_sockmap_listen__destroy(skel);
}
