brintos

brintos / linux-shallow public Read only

0
0
Text · 6.2 KiB · e122551 Raw
246 lines · c
1// SPDX-License-Identifier: GPL-2.02/* Copyright (c) Meta Platforms, Inc. and affiliates. */3 4#define _GNU_SOURCE5#include <sched.h>6#include <linux/socket.h>7#include <linux/tls.h>8#include <net/if.h>9 10#include "test_progs.h"11#include "cgroup_helpers.h"12#include "network_helpers.h"13 14#include "setget_sockopt.skel.h"15 16#define CG_NAME "/setget-sockopt-test"17 18static const char addr4_str[] = "127.0.0.1";19static const char addr6_str[] = "::1";20static struct setget_sockopt *skel;21static int cg_fd;22 23static int create_netns(void)24{25	if (!ASSERT_OK(unshare(CLONE_NEWNET), "create netns"))26		return -1;27 28	if (!ASSERT_OK(system("ip link set dev lo up"), "set lo up"))29		return -1;30 31	if (!ASSERT_OK(system("ip link add dev binddevtest1 type veth peer name binddevtest2"),32		       "add veth"))33		return -1;34 35	if (!ASSERT_OK(system("ip link set dev binddevtest1 up"),36		       "bring veth up"))37		return -1;38 39	return 0;40}41 42static void test_tcp(int family)43{44	struct setget_sockopt__bss *bss = skel->bss;45	int sfd, cfd;46 47	memset(bss, 0, sizeof(*bss));48 49	sfd = start_server(family, SOCK_STREAM,50			   family == AF_INET6 ? addr6_str : addr4_str, 0, 0);51	if (!ASSERT_GE(sfd, 0, "start_server"))52		return;53 54	cfd = connect_to_fd(sfd, 0);55	if (!ASSERT_GE(cfd, 0, "connect_to_fd_server")) {56		close(sfd);57		return;58	}59	close(sfd);60	close(cfd);61 62	ASSERT_EQ(bss->nr_listen, 1, "nr_listen");63	ASSERT_EQ(bss->nr_connect, 1, "nr_connect");64	ASSERT_EQ(bss->nr_active, 1, "nr_active");65	ASSERT_EQ(bss->nr_passive, 1, "nr_passive");66	ASSERT_EQ(bss->nr_socket_post_create, 2, "nr_socket_post_create");67	ASSERT_EQ(bss->nr_binddev, 2, "nr_bind");68}69 70static void test_udp(int family)71{72	struct setget_sockopt__bss *bss = skel->bss;73	int sfd;74 75	memset(bss, 0, sizeof(*bss));76 77	sfd = start_server(family, SOCK_DGRAM,78			   family == AF_INET6 ? addr6_str : addr4_str, 0, 0);79	if (!ASSERT_GE(sfd, 0, "start_server"))80		return;81	close(sfd);82 83	ASSERT_GE(bss->nr_socket_post_create, 1, "nr_socket_post_create");84	ASSERT_EQ(bss->nr_binddev, 1, "nr_bind");85}86 87static void test_ktls(int family)88{89	struct tls12_crypto_info_aes_gcm_128 aes128;90	struct setget_sockopt__bss *bss = skel->bss;91	int cfd = -1, sfd = -1, fd = -1, ret;92	char buf;93 94	memset(bss, 0, sizeof(*bss));95 96	sfd = start_server(family, SOCK_STREAM,97			   family == AF_INET6 ? addr6_str : addr4_str, 0, 0);98	if (!ASSERT_GE(sfd, 0, "start_server"))99		return;100	fd = connect_to_fd(sfd, 0);101	if (!ASSERT_GE(fd, 0, "connect_to_fd"))102		goto err_out;103 104	cfd = accept(sfd, NULL, 0);105	if (!ASSERT_GE(cfd, 0, "accept"))106		goto err_out;107 108	close(sfd);109	sfd = -1;110 111	/* Setup KTLS */112	ret = setsockopt(fd, IPPROTO_TCP, TCP_ULP, "tls", sizeof("tls"));113	if (!ASSERT_OK(ret, "setsockopt"))114		goto err_out;115	ret = setsockopt(cfd, IPPROTO_TCP, TCP_ULP, "tls", sizeof("tls"));116	if (!ASSERT_OK(ret, "setsockopt"))117		goto err_out;118 119	memset(&aes128, 0, sizeof(aes128));120	aes128.info.version = TLS_1_2_VERSION;121	aes128.info.cipher_type = TLS_CIPHER_AES_GCM_128;122 123	ret = setsockopt(fd, SOL_TLS, TLS_TX, &aes128, sizeof(aes128));124	if (!ASSERT_OK(ret, "setsockopt"))125		goto err_out;126 127	ret = setsockopt(cfd, SOL_TLS, TLS_RX, &aes128, sizeof(aes128));128	if (!ASSERT_OK(ret, "setsockopt"))129		goto err_out;130 131	/* KTLS is enabled */132 133	close(fd);134	/* At this point, the cfd socket is at the CLOSE_WAIT state135	 * and still run TLS protocol.  The test for136	 * BPF_TCP_CLOSE_WAIT should be run at this point.137	 */138	ret = read(cfd, &buf, sizeof(buf));139	ASSERT_EQ(ret, 0, "read");140	close(cfd);141 142	ASSERT_EQ(bss->nr_listen, 1, "nr_listen");143	ASSERT_EQ(bss->nr_connect, 1, "nr_connect");144	ASSERT_EQ(bss->nr_active, 1, "nr_active");145	ASSERT_EQ(bss->nr_passive, 1, "nr_passive");146	ASSERT_EQ(bss->nr_socket_post_create, 2, "nr_socket_post_create");147	ASSERT_EQ(bss->nr_binddev, 2, "nr_bind");148	ASSERT_EQ(bss->nr_fin_wait1, 1, "nr_fin_wait1");149	return;150 151err_out:152	close(fd);153	close(cfd);154	close(sfd);155}156 157static void test_nonstandard_opt(int family)158{159	struct setget_sockopt__bss *bss = skel->bss;160	struct bpf_link *getsockopt_link = NULL;161	int sfd = -1, fd = -1, cfd = -1, flags;162	socklen_t flagslen = sizeof(flags);163 164	memset(bss, 0, sizeof(*bss));165 166	sfd = start_server(family, SOCK_STREAM,167			   family == AF_INET6 ? addr6_str : addr4_str, 0, 0);168	if (!ASSERT_GE(sfd, 0, "start_server"))169		return;170 171	fd = connect_to_fd(sfd, 0);172	if (!ASSERT_GE(fd, 0, "connect_to_fd_server"))173		goto err_out;174 175	/* cgroup/getsockopt prog will intercept getsockopt() below and176	 * retrieve the tcp socket bpf_sock_ops_cb_flags value for the177	 * accept()ed socket; this was set earlier in the passive established178	 * callback for the accept()ed socket via bpf_setsockopt().179	 */180	getsockopt_link = bpf_program__attach_cgroup(skel->progs._getsockopt, cg_fd);181	if (!ASSERT_OK_PTR(getsockopt_link, "getsockopt prog"))182		goto err_out;183 184	cfd = accept(sfd, NULL, 0);185	if (!ASSERT_GE(cfd, 0, "accept"))186		goto err_out;187 188	if (!ASSERT_OK(getsockopt(cfd, SOL_TCP, TCP_BPF_SOCK_OPS_CB_FLAGS, &flags, &flagslen),189		       "getsockopt_flags"))190		goto err_out;191	ASSERT_EQ(flags & BPF_SOCK_OPS_STATE_CB_FLAG, BPF_SOCK_OPS_STATE_CB_FLAG,192		  "cb_flags_set");193err_out:194	close(sfd);195	if (fd != -1)196		close(fd);197	if (cfd != -1)198		close(cfd);199	bpf_link__destroy(getsockopt_link);200}201 202void test_setget_sockopt(void)203{204	cg_fd = test__join_cgroup(CG_NAME);205	if (cg_fd < 0)206		return;207 208	if (create_netns())209		goto done;210 211	skel = setget_sockopt__open();212	if (!ASSERT_OK_PTR(skel, "open skel"))213		goto done;214 215	strcpy(skel->rodata->veth, "binddevtest1");216	skel->rodata->veth_ifindex = if_nametoindex("binddevtest1");217	if (!ASSERT_GT(skel->rodata->veth_ifindex, 0, "if_nametoindex"))218		goto done;219 220	if (!ASSERT_OK(setget_sockopt__load(skel), "load skel"))221		goto done;222 223	skel->links.skops_sockopt =224		bpf_program__attach_cgroup(skel->progs.skops_sockopt, cg_fd);225	if (!ASSERT_OK_PTR(skel->links.skops_sockopt, "attach cgroup"))226		goto done;227 228	skel->links.socket_post_create =229		bpf_program__attach_cgroup(skel->progs.socket_post_create, cg_fd);230	if (!ASSERT_OK_PTR(skel->links.socket_post_create, "attach_cgroup"))231		goto done;232 233	test_tcp(AF_INET6);234	test_tcp(AF_INET);235	test_udp(AF_INET6);236	test_udp(AF_INET);237	test_ktls(AF_INET6);238	test_ktls(AF_INET);239	test_nonstandard_opt(AF_INET);240	test_nonstandard_opt(AF_INET6);241 242done:243	setget_sockopt__destroy(skel);244	close(cg_fd);245}246