1ec6c4be0SDaniel T. Lee // SPDX-License-Identifier: GPL-2.0 2ec6c4be0SDaniel T. Lee #include <linux/bpf.h> 3ec6c4be0SDaniel T. Lee #include <test_progs.h> 4ec6c4be0SDaniel T. Lee #include "cgroup_helpers.h" 5ec6c4be0SDaniel T. Lee 6ec6c4be0SDaniel T. Lee static char bpf_log_buf[4096]; 7ec6c4be0SDaniel T. Lee static bool verbose; 8ec6c4be0SDaniel T. Lee 964a4658dSDaniel T. Lee enum sock_create_test_error { 1064a4658dSDaniel T. Lee OK = 0, 1164a4658dSDaniel T. Lee DENY_CREATE, 1264a4658dSDaniel T. Lee }; 1364a4658dSDaniel T. Lee 14ec6c4be0SDaniel T. Lee static struct sock_create_test { 15ec6c4be0SDaniel T. Lee const char *descr; 16ec6c4be0SDaniel T. Lee const struct bpf_insn insns[64]; 17ec6c4be0SDaniel T. Lee enum bpf_attach_type attach_type; 18ec6c4be0SDaniel T. Lee enum bpf_attach_type expected_attach_type; 19ec6c4be0SDaniel T. Lee 20ec6c4be0SDaniel T. Lee int domain; 21ec6c4be0SDaniel T. Lee int type; 2264a4658dSDaniel T. Lee int protocol; 23ec6c4be0SDaniel T. Lee 24ec6c4be0SDaniel T. Lee int optname; 25ec6c4be0SDaniel T. Lee int optval; 2664a4658dSDaniel T. Lee enum sock_create_test_error error; 27ec6c4be0SDaniel T. Lee } tests[] = { 28ec6c4be0SDaniel T. Lee { 29ec6c4be0SDaniel T. Lee .descr = "AF_INET set priority", 30ec6c4be0SDaniel T. Lee .insns = { 31ec6c4be0SDaniel T. Lee /* r3 = 123 (priority) */ 32ec6c4be0SDaniel T. Lee BPF_MOV64_IMM(BPF_REG_3, 123), 33ec6c4be0SDaniel T. Lee BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_3, 34ec6c4be0SDaniel T. Lee offsetof(struct bpf_sock, priority)), 35ec6c4be0SDaniel T. Lee 36ec6c4be0SDaniel T. Lee /* return 1 */ 37ec6c4be0SDaniel T. Lee BPF_MOV64_IMM(BPF_REG_0, 1), 38ec6c4be0SDaniel T. Lee BPF_EXIT_INSN(), 39ec6c4be0SDaniel T. Lee }, 40ec6c4be0SDaniel T. Lee .expected_attach_type = BPF_CGROUP_INET_SOCK_CREATE, 41ec6c4be0SDaniel T. Lee .attach_type = BPF_CGROUP_INET_SOCK_CREATE, 42ec6c4be0SDaniel T. Lee 43ec6c4be0SDaniel T. Lee .domain = AF_INET, 44ec6c4be0SDaniel T. Lee .type = SOCK_DGRAM, 45ec6c4be0SDaniel T. Lee 46ec6c4be0SDaniel T. Lee .optname = SO_PRIORITY, 47ec6c4be0SDaniel T. Lee .optval = 123, 48ec6c4be0SDaniel T. Lee }, 49ec6c4be0SDaniel T. Lee { 50ec6c4be0SDaniel T. Lee .descr = "AF_INET6 set priority", 51ec6c4be0SDaniel T. Lee .insns = { 52ec6c4be0SDaniel T. Lee /* r3 = 123 (priority) */ 53ec6c4be0SDaniel T. Lee BPF_MOV64_IMM(BPF_REG_3, 123), 54ec6c4be0SDaniel T. Lee BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_3, 55ec6c4be0SDaniel T. Lee offsetof(struct bpf_sock, priority)), 56ec6c4be0SDaniel T. Lee 57ec6c4be0SDaniel T. Lee /* return 1 */ 58ec6c4be0SDaniel T. Lee BPF_MOV64_IMM(BPF_REG_0, 1), 59ec6c4be0SDaniel T. Lee BPF_EXIT_INSN(), 60ec6c4be0SDaniel T. Lee }, 61ec6c4be0SDaniel T. Lee .expected_attach_type = BPF_CGROUP_INET_SOCK_CREATE, 62ec6c4be0SDaniel T. Lee .attach_type = BPF_CGROUP_INET_SOCK_CREATE, 63ec6c4be0SDaniel T. Lee 64ec6c4be0SDaniel T. Lee .domain = AF_INET6, 65ec6c4be0SDaniel T. Lee .type = SOCK_DGRAM, 66ec6c4be0SDaniel T. Lee 67ec6c4be0SDaniel T. Lee .optname = SO_PRIORITY, 68ec6c4be0SDaniel T. Lee .optval = 123, 69ec6c4be0SDaniel T. Lee }, 70ec6c4be0SDaniel T. Lee { 71ec6c4be0SDaniel T. Lee .descr = "AF_INET set mark", 72ec6c4be0SDaniel T. Lee .insns = { 73ec6c4be0SDaniel T. Lee BPF_MOV64_REG(BPF_REG_6, BPF_REG_1), 74ec6c4be0SDaniel T. Lee 75ec6c4be0SDaniel T. Lee /* get uid of process */ 76ec6c4be0SDaniel T. Lee BPF_EMIT_CALL(BPF_FUNC_get_current_uid_gid), 77ec6c4be0SDaniel T. Lee BPF_ALU64_IMM(BPF_AND, BPF_REG_0, 0xffffffff), 78ec6c4be0SDaniel T. Lee 79ec6c4be0SDaniel T. Lee /* if uid is 0, use given mark(666), else use uid as the mark */ 80ec6c4be0SDaniel T. Lee BPF_MOV64_REG(BPF_REG_3, BPF_REG_0), 81ec6c4be0SDaniel T. Lee BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1), 82ec6c4be0SDaniel T. Lee BPF_MOV64_IMM(BPF_REG_3, 666), 83ec6c4be0SDaniel T. Lee 84ec6c4be0SDaniel T. Lee BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), 85ec6c4be0SDaniel T. Lee BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_3, 86ec6c4be0SDaniel T. Lee offsetof(struct bpf_sock, mark)), 87ec6c4be0SDaniel T. Lee 88ec6c4be0SDaniel T. Lee /* return 1 */ 89ec6c4be0SDaniel T. Lee BPF_MOV64_IMM(BPF_REG_0, 1), 90ec6c4be0SDaniel T. Lee BPF_EXIT_INSN(), 91ec6c4be0SDaniel T. Lee }, 92ec6c4be0SDaniel T. Lee .expected_attach_type = BPF_CGROUP_INET_SOCK_CREATE, 93ec6c4be0SDaniel T. Lee .attach_type = BPF_CGROUP_INET_SOCK_CREATE, 94ec6c4be0SDaniel T. Lee 95ec6c4be0SDaniel T. Lee .domain = AF_INET, 96ec6c4be0SDaniel T. Lee .type = SOCK_DGRAM, 97ec6c4be0SDaniel T. Lee 98ec6c4be0SDaniel T. Lee .optname = SO_MARK, 99ec6c4be0SDaniel T. Lee .optval = 666, 100ec6c4be0SDaniel T. Lee }, 101ec6c4be0SDaniel T. Lee { 102ec6c4be0SDaniel T. Lee .descr = "AF_INET6 set mark", 103ec6c4be0SDaniel T. Lee .insns = { 104ec6c4be0SDaniel T. Lee BPF_MOV64_REG(BPF_REG_6, BPF_REG_1), 105ec6c4be0SDaniel T. Lee 106ec6c4be0SDaniel T. Lee /* get uid of process */ 107ec6c4be0SDaniel T. Lee BPF_EMIT_CALL(BPF_FUNC_get_current_uid_gid), 108ec6c4be0SDaniel T. Lee BPF_ALU64_IMM(BPF_AND, BPF_REG_0, 0xffffffff), 109ec6c4be0SDaniel T. Lee 110ec6c4be0SDaniel T. Lee /* if uid is 0, use given mark(666), else use uid as the mark */ 111ec6c4be0SDaniel T. Lee BPF_MOV64_REG(BPF_REG_3, BPF_REG_0), 112ec6c4be0SDaniel T. Lee BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1), 113ec6c4be0SDaniel T. Lee BPF_MOV64_IMM(BPF_REG_3, 666), 114ec6c4be0SDaniel T. Lee 115ec6c4be0SDaniel T. Lee BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), 116ec6c4be0SDaniel T. Lee BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_3, 117ec6c4be0SDaniel T. Lee offsetof(struct bpf_sock, mark)), 118ec6c4be0SDaniel T. Lee 119ec6c4be0SDaniel T. Lee /* return 1 */ 120ec6c4be0SDaniel T. Lee BPF_MOV64_IMM(BPF_REG_0, 1), 121ec6c4be0SDaniel T. Lee BPF_EXIT_INSN(), 122ec6c4be0SDaniel T. Lee }, 123ec6c4be0SDaniel T. Lee .expected_attach_type = BPF_CGROUP_INET_SOCK_CREATE, 124ec6c4be0SDaniel T. Lee .attach_type = BPF_CGROUP_INET_SOCK_CREATE, 125ec6c4be0SDaniel T. Lee 126ec6c4be0SDaniel T. Lee .domain = AF_INET6, 127ec6c4be0SDaniel T. Lee .type = SOCK_DGRAM, 128ec6c4be0SDaniel T. Lee 129ec6c4be0SDaniel T. Lee .optname = SO_MARK, 130ec6c4be0SDaniel T. Lee .optval = 666, 131ec6c4be0SDaniel T. Lee }, 132ec6c4be0SDaniel T. Lee { 133ec6c4be0SDaniel T. Lee .descr = "AF_INET bound to iface", 134ec6c4be0SDaniel T. Lee .insns = { 135ec6c4be0SDaniel T. Lee /* r3 = 1 (lo interface) */ 136ec6c4be0SDaniel T. Lee BPF_MOV64_IMM(BPF_REG_3, 1), 137ec6c4be0SDaniel T. Lee BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_3, 138ec6c4be0SDaniel T. Lee offsetof(struct bpf_sock, bound_dev_if)), 139ec6c4be0SDaniel T. Lee 140ec6c4be0SDaniel T. Lee /* return 1 */ 141ec6c4be0SDaniel T. Lee BPF_MOV64_IMM(BPF_REG_0, 1), 142ec6c4be0SDaniel T. Lee BPF_EXIT_INSN(), 143ec6c4be0SDaniel T. Lee }, 144ec6c4be0SDaniel T. Lee .expected_attach_type = BPF_CGROUP_INET_SOCK_CREATE, 145ec6c4be0SDaniel T. Lee .attach_type = BPF_CGROUP_INET_SOCK_CREATE, 146ec6c4be0SDaniel T. Lee 147ec6c4be0SDaniel T. Lee .domain = AF_INET, 148ec6c4be0SDaniel T. Lee .type = SOCK_DGRAM, 149ec6c4be0SDaniel T. Lee 150ec6c4be0SDaniel T. Lee .optname = SO_BINDTOIFINDEX, 151ec6c4be0SDaniel T. Lee .optval = 1, 152ec6c4be0SDaniel T. Lee }, 153ec6c4be0SDaniel T. Lee { 154ec6c4be0SDaniel T. Lee .descr = "AF_INET6 bound to iface", 155ec6c4be0SDaniel T. Lee .insns = { 156ec6c4be0SDaniel T. Lee /* r3 = 1 (lo interface) */ 157ec6c4be0SDaniel T. Lee BPF_MOV64_IMM(BPF_REG_3, 1), 158ec6c4be0SDaniel T. Lee BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_3, 159ec6c4be0SDaniel T. Lee offsetof(struct bpf_sock, bound_dev_if)), 160ec6c4be0SDaniel T. Lee 161ec6c4be0SDaniel T. Lee /* return 1 */ 162ec6c4be0SDaniel T. Lee BPF_MOV64_IMM(BPF_REG_0, 1), 163ec6c4be0SDaniel T. Lee BPF_EXIT_INSN(), 164ec6c4be0SDaniel T. Lee }, 165ec6c4be0SDaniel T. Lee .expected_attach_type = BPF_CGROUP_INET_SOCK_CREATE, 166ec6c4be0SDaniel T. Lee .attach_type = BPF_CGROUP_INET_SOCK_CREATE, 167ec6c4be0SDaniel T. Lee 168ec6c4be0SDaniel T. Lee .domain = AF_INET6, 169ec6c4be0SDaniel T. Lee .type = SOCK_DGRAM, 170ec6c4be0SDaniel T. Lee 171ec6c4be0SDaniel T. Lee .optname = SO_BINDTOIFINDEX, 172ec6c4be0SDaniel T. Lee .optval = 1, 173ec6c4be0SDaniel T. Lee }, 17464a4658dSDaniel T. Lee { 17564a4658dSDaniel T. Lee .descr = "block AF_INET, SOCK_DGRAM, IPPROTO_ICMP socket", 17664a4658dSDaniel T. Lee .insns = { 17764a4658dSDaniel T. Lee BPF_MOV64_IMM(BPF_REG_0, 1), /* r0 = verdict */ 17864a4658dSDaniel T. Lee 17964a4658dSDaniel T. Lee /* sock->family == AF_INET */ 18064a4658dSDaniel T. Lee BPF_LDX_MEM(BPF_H, BPF_REG_2, BPF_REG_1, 18164a4658dSDaniel T. Lee offsetof(struct bpf_sock, family)), 18264a4658dSDaniel T. Lee BPF_JMP_IMM(BPF_JNE, BPF_REG_2, AF_INET, 5), 18364a4658dSDaniel T. Lee 18464a4658dSDaniel T. Lee /* sock->type == SOCK_DGRAM */ 18564a4658dSDaniel T. Lee BPF_LDX_MEM(BPF_H, BPF_REG_2, BPF_REG_1, 18664a4658dSDaniel T. Lee offsetof(struct bpf_sock, type)), 18764a4658dSDaniel T. Lee BPF_JMP_IMM(BPF_JNE, BPF_REG_2, SOCK_DGRAM, 3), 18864a4658dSDaniel T. Lee 18964a4658dSDaniel T. Lee /* sock->protocol == IPPROTO_ICMP */ 19064a4658dSDaniel T. Lee BPF_LDX_MEM(BPF_H, BPF_REG_2, BPF_REG_1, 19164a4658dSDaniel T. Lee offsetof(struct bpf_sock, protocol)), 19264a4658dSDaniel T. Lee BPF_JMP_IMM(BPF_JNE, BPF_REG_2, IPPROTO_ICMP, 1), 19364a4658dSDaniel T. Lee 19464a4658dSDaniel T. Lee /* return 0 (block) */ 19564a4658dSDaniel T. Lee BPF_MOV64_IMM(BPF_REG_0, 0), 19664a4658dSDaniel T. Lee BPF_EXIT_INSN(), 19764a4658dSDaniel T. Lee }, 19864a4658dSDaniel T. Lee .expected_attach_type = BPF_CGROUP_INET_SOCK_CREATE, 19964a4658dSDaniel T. Lee .attach_type = BPF_CGROUP_INET_SOCK_CREATE, 20064a4658dSDaniel T. Lee 20164a4658dSDaniel T. Lee .domain = AF_INET, 20264a4658dSDaniel T. Lee .type = SOCK_DGRAM, 20364a4658dSDaniel T. Lee .protocol = IPPROTO_ICMP, 20464a4658dSDaniel T. Lee 20564a4658dSDaniel T. Lee .error = DENY_CREATE, 20664a4658dSDaniel T. Lee }, 20764a4658dSDaniel T. Lee { 20864a4658dSDaniel T. Lee .descr = "block AF_INET6, SOCK_DGRAM, IPPROTO_ICMPV6 socket", 20964a4658dSDaniel T. Lee .insns = { 21064a4658dSDaniel T. Lee BPF_MOV64_IMM(BPF_REG_0, 1), /* r0 = verdict */ 21164a4658dSDaniel T. Lee 21264a4658dSDaniel T. Lee /* sock->family == AF_INET6 */ 21364a4658dSDaniel T. Lee BPF_LDX_MEM(BPF_H, BPF_REG_2, BPF_REG_1, 21464a4658dSDaniel T. Lee offsetof(struct bpf_sock, family)), 21564a4658dSDaniel T. Lee BPF_JMP_IMM(BPF_JNE, BPF_REG_2, AF_INET6, 5), 21664a4658dSDaniel T. Lee 21764a4658dSDaniel T. Lee /* sock->type == SOCK_DGRAM */ 21864a4658dSDaniel T. Lee BPF_LDX_MEM(BPF_H, BPF_REG_2, BPF_REG_1, 21964a4658dSDaniel T. Lee offsetof(struct bpf_sock, type)), 22064a4658dSDaniel T. Lee BPF_JMP_IMM(BPF_JNE, BPF_REG_2, SOCK_DGRAM, 3), 22164a4658dSDaniel T. Lee 22264a4658dSDaniel T. Lee /* sock->protocol == IPPROTO_ICMPV6 */ 22364a4658dSDaniel T. Lee BPF_LDX_MEM(BPF_H, BPF_REG_2, BPF_REG_1, 22464a4658dSDaniel T. Lee offsetof(struct bpf_sock, protocol)), 22564a4658dSDaniel T. Lee BPF_JMP_IMM(BPF_JNE, BPF_REG_2, IPPROTO_ICMPV6, 1), 22664a4658dSDaniel T. Lee 22764a4658dSDaniel T. Lee /* return 0 (block) */ 22864a4658dSDaniel T. Lee BPF_MOV64_IMM(BPF_REG_0, 0), 22964a4658dSDaniel T. Lee BPF_EXIT_INSN(), 23064a4658dSDaniel T. Lee }, 23164a4658dSDaniel T. Lee .expected_attach_type = BPF_CGROUP_INET_SOCK_CREATE, 23264a4658dSDaniel T. Lee .attach_type = BPF_CGROUP_INET_SOCK_CREATE, 23364a4658dSDaniel T. Lee 23464a4658dSDaniel T. Lee .domain = AF_INET, 23564a4658dSDaniel T. Lee .type = SOCK_DGRAM, 23664a4658dSDaniel T. Lee .protocol = IPPROTO_ICMPV6, 23764a4658dSDaniel T. Lee 23864a4658dSDaniel T. Lee .error = DENY_CREATE, 23964a4658dSDaniel T. Lee }, 240*af522f13SJordan Rife { 241*af522f13SJordan Rife .descr = "load w/o expected_attach_type (compat mode)", 242*af522f13SJordan Rife .insns = { 243*af522f13SJordan Rife /* return 1 */ 244*af522f13SJordan Rife BPF_MOV64_IMM(BPF_REG_0, 1), 245*af522f13SJordan Rife BPF_EXIT_INSN(), 246*af522f13SJordan Rife }, 247*af522f13SJordan Rife .expected_attach_type = 0, 248*af522f13SJordan Rife .attach_type = BPF_CGROUP_INET_SOCK_CREATE, 249*af522f13SJordan Rife 250*af522f13SJordan Rife .domain = AF_INET, 251*af522f13SJordan Rife .type = SOCK_STREAM, 252*af522f13SJordan Rife }, 253ec6c4be0SDaniel T. Lee }; 254ec6c4be0SDaniel T. Lee 255ec6c4be0SDaniel T. Lee static int load_prog(const struct bpf_insn *insns, 256ec6c4be0SDaniel T. Lee enum bpf_attach_type expected_attach_type) 257ec6c4be0SDaniel T. Lee { 258ec6c4be0SDaniel T. Lee LIBBPF_OPTS(bpf_prog_load_opts, opts, 259ec6c4be0SDaniel T. Lee .expected_attach_type = expected_attach_type, 260ec6c4be0SDaniel T. Lee .log_level = 2, 261ec6c4be0SDaniel T. Lee .log_buf = bpf_log_buf, 262ec6c4be0SDaniel T. Lee .log_size = sizeof(bpf_log_buf), 263ec6c4be0SDaniel T. Lee ); 264ec6c4be0SDaniel T. Lee int fd, insns_cnt = 0; 265ec6c4be0SDaniel T. Lee 266ec6c4be0SDaniel T. Lee for (; 267ec6c4be0SDaniel T. Lee insns[insns_cnt].code != (BPF_JMP | BPF_EXIT); 268ec6c4be0SDaniel T. Lee insns_cnt++) { 269ec6c4be0SDaniel T. Lee } 270ec6c4be0SDaniel T. Lee insns_cnt++; 271ec6c4be0SDaniel T. Lee 272ec6c4be0SDaniel T. Lee fd = bpf_prog_load(BPF_PROG_TYPE_CGROUP_SOCK, NULL, "GPL", insns, 273ec6c4be0SDaniel T. Lee insns_cnt, &opts); 274ec6c4be0SDaniel T. Lee if (verbose && fd < 0) 275ec6c4be0SDaniel T. Lee fprintf(stderr, "%s\n", bpf_log_buf); 276ec6c4be0SDaniel T. Lee 277ec6c4be0SDaniel T. Lee return fd; 278ec6c4be0SDaniel T. Lee } 279ec6c4be0SDaniel T. Lee 280ec6c4be0SDaniel T. Lee static int run_test(int cgroup_fd, struct sock_create_test *test) 281ec6c4be0SDaniel T. Lee { 282ec6c4be0SDaniel T. Lee int sock_fd, err, prog_fd, optval, ret = -1; 283ec6c4be0SDaniel T. Lee socklen_t optlen = sizeof(optval); 284ec6c4be0SDaniel T. Lee 285ec6c4be0SDaniel T. Lee prog_fd = load_prog(test->insns, test->expected_attach_type); 286ec6c4be0SDaniel T. Lee if (prog_fd < 0) { 287ec6c4be0SDaniel T. Lee log_err("Failed to load BPF program"); 288ec6c4be0SDaniel T. Lee return -1; 289ec6c4be0SDaniel T. Lee } 290ec6c4be0SDaniel T. Lee 291ec6c4be0SDaniel T. Lee err = bpf_prog_attach(prog_fd, cgroup_fd, test->attach_type, 0); 292ec6c4be0SDaniel T. Lee if (err < 0) { 293ec6c4be0SDaniel T. Lee log_err("Failed to attach BPF program"); 294ec6c4be0SDaniel T. Lee goto close_prog_fd; 295ec6c4be0SDaniel T. Lee } 296ec6c4be0SDaniel T. Lee 29764a4658dSDaniel T. Lee sock_fd = socket(test->domain, test->type, test->protocol); 298ec6c4be0SDaniel T. Lee if (sock_fd < 0) { 29964a4658dSDaniel T. Lee if (test->error == DENY_CREATE) 30064a4658dSDaniel T. Lee ret = 0; 30164a4658dSDaniel T. Lee else 302ec6c4be0SDaniel T. Lee log_err("Failed to create socket"); 30364a4658dSDaniel T. Lee 304ec6c4be0SDaniel T. Lee goto detach_prog; 305ec6c4be0SDaniel T. Lee } 306ec6c4be0SDaniel T. Lee 307*af522f13SJordan Rife if (test->optname) { 308ec6c4be0SDaniel T. Lee err = getsockopt(sock_fd, SOL_SOCKET, test->optname, &optval, &optlen); 309ec6c4be0SDaniel T. Lee if (err) { 310ec6c4be0SDaniel T. Lee log_err("Failed to call getsockopt"); 311ec6c4be0SDaniel T. Lee goto cleanup; 312ec6c4be0SDaniel T. Lee } 313ec6c4be0SDaniel T. Lee 314ec6c4be0SDaniel T. Lee if (optval != test->optval) { 315ec6c4be0SDaniel T. Lee errno = 0; 316ec6c4be0SDaniel T. Lee log_err("getsockopt returned unexpected optval"); 317ec6c4be0SDaniel T. Lee goto cleanup; 318ec6c4be0SDaniel T. Lee } 319*af522f13SJordan Rife } 320ec6c4be0SDaniel T. Lee 32164a4658dSDaniel T. Lee ret = test->error != OK; 322ec6c4be0SDaniel T. Lee 323ec6c4be0SDaniel T. Lee cleanup: 324ec6c4be0SDaniel T. Lee close(sock_fd); 325ec6c4be0SDaniel T. Lee detach_prog: 326ec6c4be0SDaniel T. Lee bpf_prog_detach2(prog_fd, cgroup_fd, test->attach_type); 327ec6c4be0SDaniel T. Lee close_prog_fd: 328ec6c4be0SDaniel T. Lee close(prog_fd); 329ec6c4be0SDaniel T. Lee return ret; 330ec6c4be0SDaniel T. Lee } 331ec6c4be0SDaniel T. Lee 332ec6c4be0SDaniel T. Lee void test_sock_create(void) 333ec6c4be0SDaniel T. Lee { 334ec6c4be0SDaniel T. Lee int cgroup_fd, i; 335ec6c4be0SDaniel T. Lee 336ec6c4be0SDaniel T. Lee cgroup_fd = test__join_cgroup("/sock_create"); 337ec6c4be0SDaniel T. Lee if (!ASSERT_GE(cgroup_fd, 0, "join_cgroup")) 338ec6c4be0SDaniel T. Lee return; 339ec6c4be0SDaniel T. Lee 340ec6c4be0SDaniel T. Lee for (i = 0; i < ARRAY_SIZE(tests); i++) { 341ec6c4be0SDaniel T. Lee if (!test__start_subtest(tests[i].descr)) 342ec6c4be0SDaniel T. Lee continue; 343ec6c4be0SDaniel T. Lee 344ec6c4be0SDaniel T. Lee ASSERT_OK(run_test(cgroup_fd, &tests[i]), tests[i].descr); 345ec6c4be0SDaniel T. Lee } 346ec6c4be0SDaniel T. Lee 347ec6c4be0SDaniel T. Lee close(cgroup_fd); 348ec6c4be0SDaniel T. Lee } 349