brintos

brintos / linux-shallow public Read only

0
0
Text · 6.3 KiB · 759bbb6 Raw
286 lines · c
1// SPDX-License-Identifier: GPL-2.02#include <test_progs.h>3#include "cgroup_helpers.h"4 5#include "sockopt_multi.skel.h"6 7static int run_getsockopt_test(struct sockopt_multi *obj, int cg_parent,8			       int cg_child, int sock_fd)9{10	struct bpf_link *link_parent = NULL;11	struct bpf_link *link_child = NULL;12	socklen_t optlen;13	__u8 buf;14	int err;15 16	/* Set IP_TOS to the expected value (0x80). */17 18	buf = 0x80;19	err = setsockopt(sock_fd, SOL_IP, IP_TOS, &buf, 1);20	if (err < 0) {21		log_err("Failed to call setsockopt(IP_TOS)");22		goto detach;23	}24 25	buf = 0x00;26	optlen = 1;27	err = getsockopt(sock_fd, SOL_IP, IP_TOS, &buf, &optlen);28	if (err) {29		log_err("Failed to call getsockopt(IP_TOS)");30		goto detach;31	}32 33	if (buf != 0x80) {34		log_err("Unexpected getsockopt 0x%x != 0x80 without BPF", buf);35		err = -1;36		goto detach;37	}38 39	/* Attach child program and make sure it returns new value:40	 * - kernel:      -> 0x8041	 * - child:  0x80 -> 0x9042	 */43 44	link_child = bpf_program__attach_cgroup(obj->progs._getsockopt_child,45						cg_child);46	if (!ASSERT_OK_PTR(link_child, "cg-attach-getsockopt_child"))47		goto detach;48 49	buf = 0x00;50	optlen = 1;51	err = getsockopt(sock_fd, SOL_IP, IP_TOS, &buf, &optlen);52	if (err) {53		log_err("Failed to call getsockopt(IP_TOS)");54		goto detach;55	}56 57	if (buf != 0x90) {58		log_err("Unexpected getsockopt 0x%x != 0x90", buf);59		err = -1;60		goto detach;61	}62 63	/* Attach parent program and make sure it returns new value:64	 * - kernel:      -> 0x8065	 * - child:  0x80 -> 0x9066	 * - parent: 0x90 -> 0xA067	 */68 69	link_parent = bpf_program__attach_cgroup(obj->progs._getsockopt_parent,70						 cg_parent);71	if (!ASSERT_OK_PTR(link_parent, "cg-attach-getsockopt_parent"))72		goto detach;73 74	buf = 0x00;75	optlen = 1;76	err = getsockopt(sock_fd, SOL_IP, IP_TOS, &buf, &optlen);77	if (err) {78		log_err("Failed to call getsockopt(IP_TOS)");79		goto detach;80	}81 82	if (buf != 0xA0) {83		log_err("Unexpected getsockopt 0x%x != 0xA0", buf);84		err = -1;85		goto detach;86	}87 88	/* Setting unexpected initial sockopt should return EPERM:89	 * - kernel: -> 0x4090	 * - child:  unexpected 0x40, EPERM91	 * - parent: unexpected 0x40, EPERM92	 */93 94	buf = 0x40;95	err = setsockopt(sock_fd, SOL_IP, IP_TOS, &buf, 1);96	if (err < 0) {97		log_err("Failed to call setsockopt(IP_TOS)");98		goto detach;99	}100 101	buf = 0x00;102	optlen = 1;103	err = getsockopt(sock_fd, SOL_IP, IP_TOS, &buf, &optlen);104	if (!err) {105		log_err("Unexpected success from getsockopt(IP_TOS)");106		goto detach;107	}108 109	/* Detach child program and make sure we still get EPERM:110	 * - kernel: -> 0x40111	 * - parent: unexpected 0x40, EPERM112	 */113 114	bpf_link__destroy(link_child);115	link_child = NULL;116 117	buf = 0x00;118	optlen = 1;119	err = getsockopt(sock_fd, SOL_IP, IP_TOS, &buf, &optlen);120	if (!err) {121		log_err("Unexpected success from getsockopt(IP_TOS)");122		goto detach;123	}124 125	/* Set initial value to the one the parent program expects:126	 * - kernel:      -> 0x90127	 * - parent: 0x90 -> 0xA0128	 */129 130	buf = 0x90;131	err = setsockopt(sock_fd, SOL_IP, IP_TOS, &buf, 1);132	if (err < 0) {133		log_err("Failed to call setsockopt(IP_TOS)");134		goto detach;135	}136 137	buf = 0x00;138	optlen = 1;139	err = getsockopt(sock_fd, SOL_IP, IP_TOS, &buf, &optlen);140	if (err) {141		log_err("Failed to call getsockopt(IP_TOS)");142		goto detach;143	}144 145	if (buf != 0xA0) {146		log_err("Unexpected getsockopt 0x%x != 0xA0", buf);147		err = -1;148		goto detach;149	}150 151detach:152	bpf_link__destroy(link_child);153	bpf_link__destroy(link_parent);154 155	return err;156}157 158static int run_setsockopt_test(struct sockopt_multi *obj, int cg_parent,159			       int cg_child, int sock_fd)160{161	struct bpf_link *link_parent = NULL;162	struct bpf_link *link_child = NULL;163	socklen_t optlen;164	__u8 buf;165	int err;166 167	/* Set IP_TOS to the expected value (0x80). */168 169	buf = 0x80;170	err = setsockopt(sock_fd, SOL_IP, IP_TOS, &buf, 1);171	if (err < 0) {172		log_err("Failed to call setsockopt(IP_TOS)");173		goto detach;174	}175 176	buf = 0x00;177	optlen = 1;178	err = getsockopt(sock_fd, SOL_IP, IP_TOS, &buf, &optlen);179	if (err) {180		log_err("Failed to call getsockopt(IP_TOS)");181		goto detach;182	}183 184	if (buf != 0x80) {185		log_err("Unexpected getsockopt 0x%x != 0x80 without BPF", buf);186		err = -1;187		goto detach;188	}189 190	/* Attach child program and make sure it adds 0x10. */191 192	link_child = bpf_program__attach_cgroup(obj->progs._setsockopt,193						cg_child);194	if (!ASSERT_OK_PTR(link_child, "cg-attach-setsockopt_child"))195		goto detach;196 197	buf = 0x80;198	err = setsockopt(sock_fd, SOL_IP, IP_TOS, &buf, 1);199	if (err < 0) {200		log_err("Failed to call setsockopt(IP_TOS)");201		goto detach;202	}203 204	buf = 0x00;205	optlen = 1;206	err = getsockopt(sock_fd, SOL_IP, IP_TOS, &buf, &optlen);207	if (err) {208		log_err("Failed to call getsockopt(IP_TOS)");209		goto detach;210	}211 212	if (buf != 0x80 + 0x10) {213		log_err("Unexpected getsockopt 0x%x != 0x80 + 0x10", buf);214		err = -1;215		goto detach;216	}217 218	/* Attach parent program and make sure it adds another 0x10. */219 220	link_parent = bpf_program__attach_cgroup(obj->progs._setsockopt,221						 cg_parent);222	if (!ASSERT_OK_PTR(link_parent, "cg-attach-setsockopt_parent"))223		goto detach;224 225	buf = 0x80;226	err = setsockopt(sock_fd, SOL_IP, IP_TOS, &buf, 1);227	if (err < 0) {228		log_err("Failed to call setsockopt(IP_TOS)");229		goto detach;230	}231 232	buf = 0x00;233	optlen = 1;234	err = getsockopt(sock_fd, SOL_IP, IP_TOS, &buf, &optlen);235	if (err) {236		log_err("Failed to call getsockopt(IP_TOS)");237		goto detach;238	}239 240	if (buf != 0x80 + 2 * 0x10) {241		log_err("Unexpected getsockopt 0x%x != 0x80 + 2 * 0x10", buf);242		err = -1;243		goto detach;244	}245 246detach:247	bpf_link__destroy(link_child);248	bpf_link__destroy(link_parent);249 250	return err;251}252 253void test_sockopt_multi(void)254{255	int cg_parent = -1, cg_child = -1;256	struct sockopt_multi *obj = NULL;257	int sock_fd = -1;258 259	cg_parent = test__join_cgroup("/parent");260	if (!ASSERT_GE(cg_parent, 0, "join_cgroup /parent"))261		goto out;262 263	cg_child = test__join_cgroup("/parent/child");264	if (!ASSERT_GE(cg_child, 0, "join_cgroup /parent/child"))265		goto out;266 267	obj = sockopt_multi__open_and_load();268	if (!ASSERT_OK_PTR(obj, "skel-load"))269		goto out;270 271	obj->bss->page_size = sysconf(_SC_PAGESIZE);272 273	sock_fd = socket(AF_INET, SOCK_STREAM, 0);274	if (!ASSERT_GE(sock_fd, 0, "socket"))275		goto out;276 277	ASSERT_OK(run_getsockopt_test(obj, cg_parent, cg_child, sock_fd), "getsockopt_test");278	ASSERT_OK(run_setsockopt_test(obj, cg_parent, cg_child, sock_fd), "setsockopt_test");279 280out:281	close(sock_fd);282	sockopt_multi__destroy(obj);283	close(cg_child);284	close(cg_parent);285}286