1 /* SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) */ 2 /* Copyright (c) 2021 Facebook */ 3 #ifndef __SKEL_INTERNAL_H 4 #define __SKEL_INTERNAL_H 5 6 #include <unistd.h> 7 #include <sys/syscall.h> 8 #include <sys/mman.h> 9 10 /* This file is a base header for auto-generated *.lskel.h files. 11 * Its contents will change and may become part of auto-generation in the future. 12 * 13 * The layout of bpf_[map|prog]_desc and bpf_loader_ctx is feature dependent 14 * and will change from one version of libbpf to another and features 15 * requested during loader program generation. 16 */ 17 struct bpf_map_desc { 18 union { 19 /* input for the loader prog */ 20 struct { 21 __aligned_u64 initial_value; 22 __u32 max_entries; 23 }; 24 /* output of the loader prog */ 25 struct { 26 int map_fd; 27 }; 28 }; 29 }; 30 struct bpf_prog_desc { 31 int prog_fd; 32 }; 33 34 struct bpf_loader_ctx { 35 size_t sz; 36 __u32 log_level; 37 __u32 log_size; 38 __u64 log_buf; 39 }; 40 41 struct bpf_load_and_run_opts { 42 struct bpf_loader_ctx *ctx; 43 const void *data; 44 const void *insns; 45 __u32 data_sz; 46 __u32 insns_sz; 47 const char *errstr; 48 }; 49 50 static inline int skel_sys_bpf(enum bpf_cmd cmd, union bpf_attr *attr, 51 unsigned int size) 52 { 53 return syscall(__NR_bpf, cmd, attr, size); 54 } 55 56 static inline int skel_closenz(int fd) 57 { 58 if (fd > 0) 59 return close(fd); 60 return -EINVAL; 61 } 62 63 static inline int bpf_load_and_run(struct bpf_load_and_run_opts *opts) 64 { 65 int map_fd = -1, prog_fd = -1, key = 0, err; 66 union bpf_attr attr; 67 68 map_fd = bpf_create_map_name(BPF_MAP_TYPE_ARRAY, "__loader.map", 4, 69 opts->data_sz, 1, 0); 70 if (map_fd < 0) { 71 opts->errstr = "failed to create loader map"; 72 err = -errno; 73 goto out; 74 } 75 76 err = bpf_map_update_elem(map_fd, &key, opts->data, 0); 77 if (err < 0) { 78 opts->errstr = "failed to update loader map"; 79 err = -errno; 80 goto out; 81 } 82 83 memset(&attr, 0, sizeof(attr)); 84 attr.prog_type = BPF_PROG_TYPE_SYSCALL; 85 attr.insns = (long) opts->insns; 86 attr.insn_cnt = opts->insns_sz / sizeof(struct bpf_insn); 87 attr.license = (long) "Dual BSD/GPL"; 88 memcpy(attr.prog_name, "__loader.prog", sizeof("__loader.prog")); 89 attr.fd_array = (long) &map_fd; 90 attr.log_level = opts->ctx->log_level; 91 attr.log_size = opts->ctx->log_size; 92 attr.log_buf = opts->ctx->log_buf; 93 attr.prog_flags = BPF_F_SLEEPABLE; 94 prog_fd = skel_sys_bpf(BPF_PROG_LOAD, &attr, sizeof(attr)); 95 if (prog_fd < 0) { 96 opts->errstr = "failed to load loader prog"; 97 err = -errno; 98 goto out; 99 } 100 101 memset(&attr, 0, sizeof(attr)); 102 attr.test.prog_fd = prog_fd; 103 attr.test.ctx_in = (long) opts->ctx; 104 attr.test.ctx_size_in = opts->ctx->sz; 105 err = skel_sys_bpf(BPF_PROG_RUN, &attr, sizeof(attr)); 106 if (err < 0 || (int)attr.test.retval < 0) { 107 opts->errstr = "failed to execute loader prog"; 108 if (err < 0) { 109 err = -errno; 110 } else { 111 err = (int)attr.test.retval; 112 errno = -err; 113 } 114 goto out; 115 } 116 err = 0; 117 out: 118 if (map_fd >= 0) 119 close(map_fd); 120 if (prog_fd >= 0) 121 close(prog_fd); 122 return err; 123 } 124 125 #endif 126