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