brintos

brintos / linux-shallow public Read only

0
0
Text · 4.3 KiB · 7cd8be2 Raw
173 lines · c
1// SPDX-License-Identifier: GPL-2.02#include <test_progs.h>3#include "cgroup_helpers.h"4#include "network_helpers.h"5 6#include "sockopt_inherit.skel.h"7 8#define SOL_CUSTOM			0xdeadbeef9#define CUSTOM_INHERIT1			010#define CUSTOM_INHERIT2			111#define CUSTOM_LISTENER			212 13static int verify_sockopt(int fd, int optname, const char *msg, char expected)14{15	socklen_t optlen = 1;16	char buf = 0;17	int err;18 19	err = getsockopt(fd, SOL_CUSTOM, optname, &buf, &optlen);20	if (err) {21		log_err("%s: failed to call getsockopt", msg);22		return 1;23	}24 25	printf("%s %d: got=0x%x ? expected=0x%x\n", msg, optname, buf, expected);26 27	if (buf != expected) {28		log_err("%s: unexpected getsockopt value %d != %d", msg,29			buf, expected);30		return 1;31	}32 33	return 0;34}35 36static pthread_mutex_t server_started_mtx = PTHREAD_MUTEX_INITIALIZER;37static pthread_cond_t server_started = PTHREAD_COND_INITIALIZER;38 39static void *server_thread(void *arg)40{41	struct sockaddr_storage addr;42	socklen_t len = sizeof(addr);43	int fd = *(int *)arg;44	int client_fd;45	int err = 0;46 47	err = listen(fd, 1);48 49	pthread_mutex_lock(&server_started_mtx);50	pthread_cond_signal(&server_started);51	pthread_mutex_unlock(&server_started_mtx);52 53	if (!ASSERT_GE(err, 0, "listed on socket"))54		return NULL;55 56	err += verify_sockopt(fd, CUSTOM_INHERIT1, "listen", 1);57	err += verify_sockopt(fd, CUSTOM_INHERIT2, "listen", 1);58	err += verify_sockopt(fd, CUSTOM_LISTENER, "listen", 1);59 60	client_fd = accept(fd, (struct sockaddr *)&addr, &len);61	if (!ASSERT_GE(client_fd, 0, "accept client"))62		return NULL;63 64	err += verify_sockopt(client_fd, CUSTOM_INHERIT1, "accept", 1);65	err += verify_sockopt(client_fd, CUSTOM_INHERIT2, "accept", 1);66	err += verify_sockopt(client_fd, CUSTOM_LISTENER, "accept", 0);67 68	close(client_fd);69 70	return (void *)(long)err;71}72 73static int custom_cb(int fd, void *opts)74{75	char buf;76	int err;77	int i;78 79	for (i = CUSTOM_INHERIT1; i <= CUSTOM_LISTENER; i++) {80		buf = 0x01;81		err = setsockopt(fd, SOL_CUSTOM, i, &buf, 1);82		if (err) {83			log_err("Failed to call setsockopt(%d)", i);84			return -1;85		}86	}87 88	return 0;89}90 91static void run_test(int cgroup_fd)92{93	struct bpf_link *link_getsockopt = NULL;94	struct bpf_link *link_setsockopt = NULL;95	struct network_helper_opts opts = {96		.post_socket_cb = custom_cb,97	};98	int server_fd = -1, client_fd;99	struct sockaddr_in addr = {100		.sin_family = AF_INET,101		.sin_addr.s_addr = htonl(INADDR_LOOPBACK),102	};103	struct sockopt_inherit *obj;104	void *server_err;105	pthread_t tid;106	int err;107 108	obj = sockopt_inherit__open_and_load();109	if (!ASSERT_OK_PTR(obj, "skel-load"))110		return;111 112	obj->bss->page_size = sysconf(_SC_PAGESIZE);113 114	link_getsockopt = bpf_program__attach_cgroup(obj->progs._getsockopt,115						     cgroup_fd);116	if (!ASSERT_OK_PTR(link_getsockopt, "cg-attach-getsockopt"))117		goto close_bpf_object;118 119	link_setsockopt = bpf_program__attach_cgroup(obj->progs._setsockopt,120						     cgroup_fd);121	if (!ASSERT_OK_PTR(link_setsockopt, "cg-attach-setsockopt"))122		goto close_bpf_object;123 124	server_fd = start_server_addr(SOCK_STREAM, (struct sockaddr_storage *)&addr,125				      sizeof(addr), &opts);126	if (!ASSERT_GE(server_fd, 0, "start_server"))127		goto close_bpf_object;128 129	pthread_mutex_lock(&server_started_mtx);130	if (!ASSERT_OK(pthread_create(&tid, NULL, server_thread,131				      (void *)&server_fd), "pthread_create")) {132		pthread_mutex_unlock(&server_started_mtx);133		goto close_server_fd;134	}135	pthread_cond_wait(&server_started, &server_started_mtx);136	pthread_mutex_unlock(&server_started_mtx);137 138	client_fd = connect_to_fd(server_fd, 0);139	if (!ASSERT_GE(client_fd, 0, "connect_to_server"))140		goto close_server_fd;141 142	ASSERT_OK(verify_sockopt(client_fd, CUSTOM_INHERIT1, "connect", 0), "verify_sockopt1");143	ASSERT_OK(verify_sockopt(client_fd, CUSTOM_INHERIT2, "connect", 0), "verify_sockopt2");144	ASSERT_OK(verify_sockopt(client_fd, CUSTOM_LISTENER, "connect", 0), "verify_sockopt ener");145 146	pthread_join(tid, &server_err);147 148	err = (int)(long)server_err;149	ASSERT_OK(err, "pthread_join retval");150 151	close(client_fd);152 153close_server_fd:154	close(server_fd);155close_bpf_object:156	bpf_link__destroy(link_getsockopt);157	bpf_link__destroy(link_setsockopt);158 159	sockopt_inherit__destroy(obj);160}161 162void test_sockopt_inherit(void)163{164	int cgroup_fd;165 166	cgroup_fd = test__join_cgroup("/sockopt_inherit");167	if (!ASSERT_GE(cgroup_fd, 0, "join_cgroup"))168		return;169 170	run_test(cgroup_fd);171	close(cgroup_fd);172}173