xref: /openbmc/linux/tools/testing/selftests/bpf/prog_tests/sk_assign.c (revision 9a87ffc99ec8eb8d35eed7c4f816d75f5cc9662e)
12d7824ffSLorenz Bauer // SPDX-License-Identifier: GPL-2.0
22d7824ffSLorenz Bauer // Copyright (c) 2018 Facebook
32d7824ffSLorenz Bauer // Copyright (c) 2019 Cloudflare
42d7824ffSLorenz Bauer // Copyright (c) 2020 Isovalent, Inc.
52d7824ffSLorenz Bauer /*
62d7824ffSLorenz Bauer  * Test that the socket assign program is able to redirect traffic towards a
72d7824ffSLorenz Bauer  * socket, regardless of whether the port or address destination of the traffic
82d7824ffSLorenz Bauer  * matches the port.
92d7824ffSLorenz Bauer  */
102d7824ffSLorenz Bauer 
112d7824ffSLorenz Bauer #define _GNU_SOURCE
122d7824ffSLorenz Bauer #include <fcntl.h>
132d7824ffSLorenz Bauer #include <signal.h>
142d7824ffSLorenz Bauer #include <stdlib.h>
152d7824ffSLorenz Bauer #include <unistd.h>
162d7824ffSLorenz Bauer 
172d7824ffSLorenz Bauer #include "test_progs.h"
182d7824ffSLorenz Bauer 
192d7824ffSLorenz Bauer #define BIND_PORT 1234
202d7824ffSLorenz Bauer #define CONNECT_PORT 4321
212d7824ffSLorenz Bauer #define TEST_DADDR (0xC0A80203)
222d7824ffSLorenz Bauer #define NS_SELF "/proc/self/ns/net"
230b9ad56bSJakub Sitnicki #define SERVER_MAP_PATH "/sys/fs/bpf/tc/globals/server_map"
242d7824ffSLorenz Bauer 
252d7824ffSLorenz Bauer static const struct timeval timeo_sec = { .tv_sec = 3 };
262d7824ffSLorenz Bauer static const size_t timeo_optlen = sizeof(timeo_sec);
272d7824ffSLorenz Bauer static int stop, duration;
282d7824ffSLorenz Bauer 
292d7824ffSLorenz Bauer static bool
configure_stack(void)302d7824ffSLorenz Bauer configure_stack(void)
312d7824ffSLorenz Bauer {
32*7ce878caSIlya Leoshkevich 	char tc_version[128];
332d7824ffSLorenz Bauer 	char tc_cmd[BUFSIZ];
34*7ce878caSIlya Leoshkevich 	char *prog;
35*7ce878caSIlya Leoshkevich 	FILE *tc;
36*7ce878caSIlya Leoshkevich 
37*7ce878caSIlya Leoshkevich 	/* Check whether tc is built with libbpf. */
38*7ce878caSIlya Leoshkevich 	tc = popen("tc -V", "r");
39*7ce878caSIlya Leoshkevich 	if (CHECK_FAIL(!tc))
40*7ce878caSIlya Leoshkevich 		return false;
41*7ce878caSIlya Leoshkevich 	if (CHECK_FAIL(!fgets(tc_version, sizeof(tc_version), tc)))
42*7ce878caSIlya Leoshkevich 		return false;
43*7ce878caSIlya Leoshkevich 	if (strstr(tc_version, ", libbpf "))
44*7ce878caSIlya Leoshkevich 		prog = "test_sk_assign_libbpf.bpf.o";
45*7ce878caSIlya Leoshkevich 	else
46*7ce878caSIlya Leoshkevich 		prog = "test_sk_assign.bpf.o";
47*7ce878caSIlya Leoshkevich 	if (CHECK_FAIL(pclose(tc)))
48*7ce878caSIlya Leoshkevich 		return false;
492d7824ffSLorenz Bauer 
502d7824ffSLorenz Bauer 	/* Move to a new networking namespace */
512d7824ffSLorenz Bauer 	if (CHECK_FAIL(unshare(CLONE_NEWNET)))
522d7824ffSLorenz Bauer 		return false;
532d7824ffSLorenz Bauer 
542d7824ffSLorenz Bauer 	/* Configure necessary links, routes */
552d7824ffSLorenz Bauer 	if (CHECK_FAIL(system("ip link set dev lo up")))
562d7824ffSLorenz Bauer 		return false;
572d7824ffSLorenz Bauer 	if (CHECK_FAIL(system("ip route add local default dev lo")))
582d7824ffSLorenz Bauer 		return false;
592d7824ffSLorenz Bauer 	if (CHECK_FAIL(system("ip -6 route add local default dev lo")))
602d7824ffSLorenz Bauer 		return false;
612d7824ffSLorenz Bauer 
622d7824ffSLorenz Bauer 	/* Load qdisc, BPF program */
632d7824ffSLorenz Bauer 	if (CHECK_FAIL(system("tc qdisc add dev lo clsact")))
642d7824ffSLorenz Bauer 		return false;
65*7ce878caSIlya Leoshkevich 	sprintf(tc_cmd, "%s %s %s %s %s", "tc filter add dev lo ingress bpf",
66*7ce878caSIlya Leoshkevich 		       "direct-action object-file", prog,
67c22bdd28SAndrii Nakryiko 		       "section tc",
680fcdfffeSYonghong Song 		       (env.verbosity < VERBOSE_VERY) ? " 2>/dev/null" : "verbose");
692d7824ffSLorenz Bauer 	if (CHECK(system(tc_cmd), "BPF load failed;",
702d7824ffSLorenz Bauer 		  "run with -vv for more info\n"))
712d7824ffSLorenz Bauer 		return false;
722d7824ffSLorenz Bauer 
732d7824ffSLorenz Bauer 	return true;
742d7824ffSLorenz Bauer }
752d7824ffSLorenz Bauer 
762d7824ffSLorenz Bauer static int
start_server(const struct sockaddr * addr,socklen_t len,int type)772d7824ffSLorenz Bauer start_server(const struct sockaddr *addr, socklen_t len, int type)
782d7824ffSLorenz Bauer {
792d7824ffSLorenz Bauer 	int fd;
802d7824ffSLorenz Bauer 
812d7824ffSLorenz Bauer 	fd = socket(addr->sa_family, type, 0);
822d7824ffSLorenz Bauer 	if (CHECK_FAIL(fd == -1))
832d7824ffSLorenz Bauer 		goto out;
842d7824ffSLorenz Bauer 	if (CHECK_FAIL(setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &timeo_sec,
852d7824ffSLorenz Bauer 				  timeo_optlen)))
862d7824ffSLorenz Bauer 		goto close_out;
872d7824ffSLorenz Bauer 	if (CHECK_FAIL(bind(fd, addr, len) == -1))
882d7824ffSLorenz Bauer 		goto close_out;
898a02a170SJoe Stringer 	if (type == SOCK_STREAM && CHECK_FAIL(listen(fd, 128) == -1))
902d7824ffSLorenz Bauer 		goto close_out;
912d7824ffSLorenz Bauer 
922d7824ffSLorenz Bauer 	goto out;
932d7824ffSLorenz Bauer close_out:
942d7824ffSLorenz Bauer 	close(fd);
952d7824ffSLorenz Bauer 	fd = -1;
962d7824ffSLorenz Bauer out:
972d7824ffSLorenz Bauer 	return fd;
982d7824ffSLorenz Bauer }
992d7824ffSLorenz Bauer 
1002d7824ffSLorenz Bauer static int
connect_to_server(const struct sockaddr * addr,socklen_t len,int type)1012d7824ffSLorenz Bauer connect_to_server(const struct sockaddr *addr, socklen_t len, int type)
1022d7824ffSLorenz Bauer {
1032d7824ffSLorenz Bauer 	int fd = -1;
1042d7824ffSLorenz Bauer 
1052d7824ffSLorenz Bauer 	fd = socket(addr->sa_family, type, 0);
1062d7824ffSLorenz Bauer 	if (CHECK_FAIL(fd == -1))
1072d7824ffSLorenz Bauer 		goto out;
1082d7824ffSLorenz Bauer 	if (CHECK_FAIL(setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &timeo_sec,
1092d7824ffSLorenz Bauer 				  timeo_optlen)))
1102d7824ffSLorenz Bauer 		goto close_out;
1112d7824ffSLorenz Bauer 	if (CHECK_FAIL(connect(fd, addr, len)))
1122d7824ffSLorenz Bauer 		goto close_out;
1132d7824ffSLorenz Bauer 
1142d7824ffSLorenz Bauer 	goto out;
1152d7824ffSLorenz Bauer close_out:
1162d7824ffSLorenz Bauer 	close(fd);
1172d7824ffSLorenz Bauer 	fd = -1;
1182d7824ffSLorenz Bauer out:
1192d7824ffSLorenz Bauer 	return fd;
1202d7824ffSLorenz Bauer }
1212d7824ffSLorenz Bauer 
1222d7824ffSLorenz Bauer static in_port_t
get_port(int fd)1232d7824ffSLorenz Bauer get_port(int fd)
1242d7824ffSLorenz Bauer {
1252d7824ffSLorenz Bauer 	struct sockaddr_storage ss;
1262d7824ffSLorenz Bauer 	socklen_t slen = sizeof(ss);
1272d7824ffSLorenz Bauer 	in_port_t port = 0;
1282d7824ffSLorenz Bauer 
1292d7824ffSLorenz Bauer 	if (CHECK_FAIL(getsockname(fd, (struct sockaddr *)&ss, &slen)))
1302d7824ffSLorenz Bauer 		return port;
1312d7824ffSLorenz Bauer 
1322d7824ffSLorenz Bauer 	switch (ss.ss_family) {
1332d7824ffSLorenz Bauer 	case AF_INET:
1342d7824ffSLorenz Bauer 		port = ((struct sockaddr_in *)&ss)->sin_port;
1352d7824ffSLorenz Bauer 		break;
1362d7824ffSLorenz Bauer 	case AF_INET6:
1372d7824ffSLorenz Bauer 		port = ((struct sockaddr_in6 *)&ss)->sin6_port;
1382d7824ffSLorenz Bauer 		break;
1392d7824ffSLorenz Bauer 	default:
1402d7824ffSLorenz Bauer 		CHECK(1, "Invalid address family", "%d\n", ss.ss_family);
1412d7824ffSLorenz Bauer 	}
1422d7824ffSLorenz Bauer 	return port;
1432d7824ffSLorenz Bauer }
1442d7824ffSLorenz Bauer 
1458a02a170SJoe Stringer static ssize_t
rcv_msg(int srv_client,int type)1468a02a170SJoe Stringer rcv_msg(int srv_client, int type)
1478a02a170SJoe Stringer {
1488a02a170SJoe Stringer 	char buf[BUFSIZ];
1498a02a170SJoe Stringer 
1508a02a170SJoe Stringer 	if (type == SOCK_STREAM)
1518a02a170SJoe Stringer 		return read(srv_client, &buf, sizeof(buf));
1528a02a170SJoe Stringer 	else
153*7ce878caSIlya Leoshkevich 		return recvfrom(srv_client, &buf, sizeof(buf), 0, NULL, NULL);
1548a02a170SJoe Stringer }
1558a02a170SJoe Stringer 
1562d7824ffSLorenz Bauer static int
run_test(int server_fd,const struct sockaddr * addr,socklen_t len,int type)1572d7824ffSLorenz Bauer run_test(int server_fd, const struct sockaddr *addr, socklen_t len, int type)
1582d7824ffSLorenz Bauer {
1592d7824ffSLorenz Bauer 	int client = -1, srv_client = -1;
1602d7824ffSLorenz Bauer 	char buf[] = "testing";
1612d7824ffSLorenz Bauer 	in_port_t port;
1622d7824ffSLorenz Bauer 	int ret = 1;
1632d7824ffSLorenz Bauer 
1642d7824ffSLorenz Bauer 	client = connect_to_server(addr, len, type);
1652d7824ffSLorenz Bauer 	if (client == -1) {
1662d7824ffSLorenz Bauer 		perror("Cannot connect to server");
1672d7824ffSLorenz Bauer 		goto out;
1682d7824ffSLorenz Bauer 	}
1692d7824ffSLorenz Bauer 
1708a02a170SJoe Stringer 	if (type == SOCK_STREAM) {
1712d7824ffSLorenz Bauer 		srv_client = accept(server_fd, NULL, NULL);
1722d7824ffSLorenz Bauer 		if (CHECK_FAIL(srv_client == -1)) {
1732d7824ffSLorenz Bauer 			perror("Can't accept connection");
1742d7824ffSLorenz Bauer 			goto out;
1752d7824ffSLorenz Bauer 		}
1768a02a170SJoe Stringer 	} else {
1778a02a170SJoe Stringer 		srv_client = server_fd;
1788a02a170SJoe Stringer 	}
1792d7824ffSLorenz Bauer 	if (CHECK_FAIL(write(client, buf, sizeof(buf)) != sizeof(buf))) {
1802d7824ffSLorenz Bauer 		perror("Can't write on client");
1812d7824ffSLorenz Bauer 		goto out;
1822d7824ffSLorenz Bauer 	}
1838a02a170SJoe Stringer 	if (CHECK_FAIL(rcv_msg(srv_client, type) != sizeof(buf))) {
1842d7824ffSLorenz Bauer 		perror("Can't read on server");
1852d7824ffSLorenz Bauer 		goto out;
1862d7824ffSLorenz Bauer 	}
1872d7824ffSLorenz Bauer 
1882d7824ffSLorenz Bauer 	port = get_port(srv_client);
1892d7824ffSLorenz Bauer 	if (CHECK_FAIL(!port))
1902d7824ffSLorenz Bauer 		goto out;
1918a02a170SJoe Stringer 	/* SOCK_STREAM is connected via accept(), so the server's local address
1928a02a170SJoe Stringer 	 * will be the CONNECT_PORT rather than the BIND port that corresponds
1938a02a170SJoe Stringer 	 * to the listen socket. SOCK_DGRAM on the other hand is connectionless
1948a02a170SJoe Stringer 	 * so we can't really do the same check there; the server doesn't ever
1958a02a170SJoe Stringer 	 * create a socket with CONNECT_PORT.
1968a02a170SJoe Stringer 	 */
1978a02a170SJoe Stringer 	if (type == SOCK_STREAM &&
1988a02a170SJoe Stringer 	    CHECK(port != htons(CONNECT_PORT), "Expected", "port %u but got %u",
1992d7824ffSLorenz Bauer 		  CONNECT_PORT, ntohs(port)))
2002d7824ffSLorenz Bauer 		goto out;
2018a02a170SJoe Stringer 	else if (type == SOCK_DGRAM &&
2028a02a170SJoe Stringer 		 CHECK(port != htons(BIND_PORT), "Expected",
2038a02a170SJoe Stringer 		       "port %u but got %u", BIND_PORT, ntohs(port)))
2048a02a170SJoe Stringer 		goto out;
2052d7824ffSLorenz Bauer 
2062d7824ffSLorenz Bauer 	ret = 0;
2072d7824ffSLorenz Bauer out:
2082d7824ffSLorenz Bauer 	close(client);
2092d7824ffSLorenz Bauer 	if (srv_client != server_fd)
2102d7824ffSLorenz Bauer 		close(srv_client);
2112d7824ffSLorenz Bauer 	if (ret)
2122d7824ffSLorenz Bauer 		WRITE_ONCE(stop, 1);
2132d7824ffSLorenz Bauer 	return ret;
2142d7824ffSLorenz Bauer }
2152d7824ffSLorenz Bauer 
2162d7824ffSLorenz Bauer static void
prepare_addr(struct sockaddr * addr,int family,__u16 port,bool rewrite_addr)2172d7824ffSLorenz Bauer prepare_addr(struct sockaddr *addr, int family, __u16 port, bool rewrite_addr)
2182d7824ffSLorenz Bauer {
2192d7824ffSLorenz Bauer 	struct sockaddr_in *addr4;
2202d7824ffSLorenz Bauer 	struct sockaddr_in6 *addr6;
2212d7824ffSLorenz Bauer 
2222d7824ffSLorenz Bauer 	switch (family) {
2232d7824ffSLorenz Bauer 	case AF_INET:
2242d7824ffSLorenz Bauer 		addr4 = (struct sockaddr_in *)addr;
2252d7824ffSLorenz Bauer 		memset(addr4, 0, sizeof(*addr4));
2262d7824ffSLorenz Bauer 		addr4->sin_family = family;
2272d7824ffSLorenz Bauer 		addr4->sin_port = htons(port);
2282d7824ffSLorenz Bauer 		if (rewrite_addr)
2292d7824ffSLorenz Bauer 			addr4->sin_addr.s_addr = htonl(TEST_DADDR);
2302d7824ffSLorenz Bauer 		else
2312d7824ffSLorenz Bauer 			addr4->sin_addr.s_addr = htonl(INADDR_LOOPBACK);
2322d7824ffSLorenz Bauer 		break;
2332d7824ffSLorenz Bauer 	case AF_INET6:
2342d7824ffSLorenz Bauer 		addr6 = (struct sockaddr_in6 *)addr;
2352d7824ffSLorenz Bauer 		memset(addr6, 0, sizeof(*addr6));
2362d7824ffSLorenz Bauer 		addr6->sin6_family = family;
2372d7824ffSLorenz Bauer 		addr6->sin6_port = htons(port);
2382d7824ffSLorenz Bauer 		addr6->sin6_addr = in6addr_loopback;
2392d7824ffSLorenz Bauer 		if (rewrite_addr)
2402d7824ffSLorenz Bauer 			addr6->sin6_addr.s6_addr32[3] = htonl(TEST_DADDR);
2412d7824ffSLorenz Bauer 		break;
2422d7824ffSLorenz Bauer 	default:
2432d7824ffSLorenz Bauer 		fprintf(stderr, "Invalid family %d", family);
2442d7824ffSLorenz Bauer 	}
2452d7824ffSLorenz Bauer }
2462d7824ffSLorenz Bauer 
2472d7824ffSLorenz Bauer struct test_sk_cfg {
2482d7824ffSLorenz Bauer 	const char *name;
2492d7824ffSLorenz Bauer 	int family;
2502d7824ffSLorenz Bauer 	struct sockaddr *addr;
2512d7824ffSLorenz Bauer 	socklen_t len;
2522d7824ffSLorenz Bauer 	int type;
2532d7824ffSLorenz Bauer 	bool rewrite_addr;
2542d7824ffSLorenz Bauer };
2552d7824ffSLorenz Bauer 
2562d7824ffSLorenz Bauer #define TEST(NAME, FAMILY, TYPE, REWRITE)				\
2572d7824ffSLorenz Bauer {									\
2582d7824ffSLorenz Bauer 	.name = NAME,							\
2592d7824ffSLorenz Bauer 	.family = FAMILY,						\
2602d7824ffSLorenz Bauer 	.addr = (FAMILY == AF_INET) ? (struct sockaddr *)&addr4		\
2612d7824ffSLorenz Bauer 				    : (struct sockaddr *)&addr6,	\
2622d7824ffSLorenz Bauer 	.len = (FAMILY == AF_INET) ? sizeof(addr4) : sizeof(addr6),	\
2632d7824ffSLorenz Bauer 	.type = TYPE,							\
2642d7824ffSLorenz Bauer 	.rewrite_addr = REWRITE,					\
2652d7824ffSLorenz Bauer }
2662d7824ffSLorenz Bauer 
test_sk_assign(void)2672d7824ffSLorenz Bauer void test_sk_assign(void)
2682d7824ffSLorenz Bauer {
2692d7824ffSLorenz Bauer 	struct sockaddr_in addr4;
2702d7824ffSLorenz Bauer 	struct sockaddr_in6 addr6;
2712d7824ffSLorenz Bauer 	struct test_sk_cfg tests[] = {
2722d7824ffSLorenz Bauer 		TEST("ipv4 tcp port redir", AF_INET, SOCK_STREAM, false),
2732d7824ffSLorenz Bauer 		TEST("ipv4 tcp addr redir", AF_INET, SOCK_STREAM, true),
2742d7824ffSLorenz Bauer 		TEST("ipv6 tcp port redir", AF_INET6, SOCK_STREAM, false),
2752d7824ffSLorenz Bauer 		TEST("ipv6 tcp addr redir", AF_INET6, SOCK_STREAM, true),
2768a02a170SJoe Stringer 		TEST("ipv4 udp port redir", AF_INET, SOCK_DGRAM, false),
2778a02a170SJoe Stringer 		TEST("ipv4 udp addr redir", AF_INET, SOCK_DGRAM, true),
2788a02a170SJoe Stringer 		TEST("ipv6 udp port redir", AF_INET6, SOCK_DGRAM, false),
2798a02a170SJoe Stringer 		TEST("ipv6 udp addr redir", AF_INET6, SOCK_DGRAM, true),
2802d7824ffSLorenz Bauer 	};
281b6ed6cf4SIlya Leoshkevich 	__s64 server = -1;
2820b9ad56bSJakub Sitnicki 	int server_map;
2832d7824ffSLorenz Bauer 	int self_net;
28437a6a9e7SAndrii Nakryiko 	int i;
2852d7824ffSLorenz Bauer 
2862d7824ffSLorenz Bauer 	self_net = open(NS_SELF, O_RDONLY);
2872d7824ffSLorenz Bauer 	if (CHECK_FAIL(self_net < 0)) {
2882d7824ffSLorenz Bauer 		perror("Unable to open "NS_SELF);
2892d7824ffSLorenz Bauer 		return;
2902d7824ffSLorenz Bauer 	}
2912d7824ffSLorenz Bauer 
2922d7824ffSLorenz Bauer 	if (!configure_stack()) {
2932d7824ffSLorenz Bauer 		perror("configure_stack");
2942d7824ffSLorenz Bauer 		goto cleanup;
2952d7824ffSLorenz Bauer 	}
2962d7824ffSLorenz Bauer 
2970b9ad56bSJakub Sitnicki 	server_map = bpf_obj_get(SERVER_MAP_PATH);
2980b9ad56bSJakub Sitnicki 	if (CHECK_FAIL(server_map < 0)) {
2990b9ad56bSJakub Sitnicki 		perror("Unable to open " SERVER_MAP_PATH);
3000b9ad56bSJakub Sitnicki 		goto cleanup;
3010b9ad56bSJakub Sitnicki 	}
3020b9ad56bSJakub Sitnicki 
30337a6a9e7SAndrii Nakryiko 	for (i = 0; i < ARRAY_SIZE(tests) && !READ_ONCE(stop); i++) {
3042d7824ffSLorenz Bauer 		struct test_sk_cfg *test = &tests[i];
3052d7824ffSLorenz Bauer 		const struct sockaddr *addr;
3060b9ad56bSJakub Sitnicki 		const int zero = 0;
3070b9ad56bSJakub Sitnicki 		int err;
3082d7824ffSLorenz Bauer 
3092d7824ffSLorenz Bauer 		if (!test__start_subtest(test->name))
3102d7824ffSLorenz Bauer 			continue;
3112d7824ffSLorenz Bauer 		prepare_addr(test->addr, test->family, BIND_PORT, false);
3122d7824ffSLorenz Bauer 		addr = (const struct sockaddr *)test->addr;
3132d7824ffSLorenz Bauer 		server = start_server(addr, test->len, test->type);
3142d7824ffSLorenz Bauer 		if (server == -1)
3150b9ad56bSJakub Sitnicki 			goto close;
3160b9ad56bSJakub Sitnicki 
3170b9ad56bSJakub Sitnicki 		err = bpf_map_update_elem(server_map, &zero, &server, BPF_ANY);
3180b9ad56bSJakub Sitnicki 		if (CHECK_FAIL(err)) {
3190b9ad56bSJakub Sitnicki 			perror("Unable to update server_map");
3200b9ad56bSJakub Sitnicki 			goto close;
3210b9ad56bSJakub Sitnicki 		}
3222d7824ffSLorenz Bauer 
3232d7824ffSLorenz Bauer 		/* connect to unbound ports */
3242d7824ffSLorenz Bauer 		prepare_addr(test->addr, test->family, CONNECT_PORT,
3252d7824ffSLorenz Bauer 			     test->rewrite_addr);
3262d7824ffSLorenz Bauer 		if (run_test(server, addr, test->len, test->type))
3272d7824ffSLorenz Bauer 			goto close;
3282d7824ffSLorenz Bauer 
3292d7824ffSLorenz Bauer 		close(server);
3302d7824ffSLorenz Bauer 		server = -1;
3312d7824ffSLorenz Bauer 	}
3322d7824ffSLorenz Bauer 
3332d7824ffSLorenz Bauer close:
3342d7824ffSLorenz Bauer 	close(server);
3350b9ad56bSJakub Sitnicki 	close(server_map);
3362d7824ffSLorenz Bauer cleanup:
3370b9ad56bSJakub Sitnicki 	if (CHECK_FAIL(unlink(SERVER_MAP_PATH)))
3380b9ad56bSJakub Sitnicki 		perror("Unable to unlink " SERVER_MAP_PATH);
3392d7824ffSLorenz Bauer 	if (CHECK_FAIL(setns(self_net, CLONE_NEWNET)))
3402d7824ffSLorenz Bauer 		perror("Failed to setns("NS_SELF")");
3412d7824ffSLorenz Bauer 	close(self_net);
3422d7824ffSLorenz Bauer }
343