^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * common eBPF ELF operations.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (C) 2013-2015 Alexei Starovoitov <ast@kernel.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Copyright (C) 2015 Wang Nan <wangnan0@huawei.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Copyright (C) 2015 Huawei Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * This program is free software; you can redistribute it and/or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * modify it under the terms of the GNU Lesser General Public
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * License as published by the Free Software Foundation;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * version 2.1 of the License (not later!)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * This program is distributed in the hope that it will be useful,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * but WITHOUT ANY WARRANTY; without even the implied warranty of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * GNU Lesser General Public License for more details.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * You should have received a copy of the GNU Lesser General Public
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * License along with this program; if not, see <http://www.gnu.org/licenses>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <stdlib.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <memory.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <unistd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <asm/unistd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <linux/bpf.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include "bpf.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include "libbpf.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include "libbpf_internal.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) * When building perf, unistd.h is overridden. __NR_bpf is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) * required to be defined explicitly.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #ifndef __NR_bpf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) # if defined(__i386__)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) # define __NR_bpf 357
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) # elif defined(__x86_64__)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) # define __NR_bpf 321
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) # elif defined(__aarch64__)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) # define __NR_bpf 280
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) # elif defined(__sparc__)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) # define __NR_bpf 349
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) # elif defined(__s390__)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) # define __NR_bpf 351
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) # elif defined(__arc__)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) # define __NR_bpf 280
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) # else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) # error __NR_bpf not defined. libbpf does not support your arch.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) # endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) static inline __u64 ptr_to_u64(const void *ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) return (__u64) (unsigned long) ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) static inline int sys_bpf(enum bpf_cmd cmd, union bpf_attr *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) unsigned int size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) return syscall(__NR_bpf, cmd, attr, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) static inline int sys_bpf_prog_load(union bpf_attr *attr, unsigned int size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) int fd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) fd = sys_bpf(BPF_PROG_LOAD, attr, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) } while (fd < 0 && errno == EAGAIN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) return fd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) int bpf_create_map_xattr(const struct bpf_create_map_attr *create_attr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) union bpf_attr attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) memset(&attr, '\0', sizeof(attr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) attr.map_type = create_attr->map_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) attr.key_size = create_attr->key_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) attr.value_size = create_attr->value_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) attr.max_entries = create_attr->max_entries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) attr.map_flags = create_attr->map_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) if (create_attr->name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) memcpy(attr.map_name, create_attr->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) min(strlen(create_attr->name), BPF_OBJ_NAME_LEN - 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) attr.numa_node = create_attr->numa_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) attr.btf_fd = create_attr->btf_fd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) attr.btf_key_type_id = create_attr->btf_key_type_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) attr.btf_value_type_id = create_attr->btf_value_type_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) attr.map_ifindex = create_attr->map_ifindex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) if (attr.map_type == BPF_MAP_TYPE_STRUCT_OPS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) attr.btf_vmlinux_value_type_id =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) create_attr->btf_vmlinux_value_type_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) attr.inner_map_fd = create_attr->inner_map_fd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) return sys_bpf(BPF_MAP_CREATE, &attr, sizeof(attr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) int bpf_create_map_node(enum bpf_map_type map_type, const char *name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) int key_size, int value_size, int max_entries,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) __u32 map_flags, int node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) struct bpf_create_map_attr map_attr = {};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) map_attr.name = name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) map_attr.map_type = map_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) map_attr.map_flags = map_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) map_attr.key_size = key_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) map_attr.value_size = value_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) map_attr.max_entries = max_entries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) if (node >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) map_attr.numa_node = node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) map_attr.map_flags |= BPF_F_NUMA_NODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) return bpf_create_map_xattr(&map_attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) int bpf_create_map(enum bpf_map_type map_type, int key_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) int value_size, int max_entries, __u32 map_flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) struct bpf_create_map_attr map_attr = {};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) map_attr.map_type = map_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) map_attr.map_flags = map_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) map_attr.key_size = key_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) map_attr.value_size = value_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) map_attr.max_entries = max_entries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) return bpf_create_map_xattr(&map_attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) int bpf_create_map_name(enum bpf_map_type map_type, const char *name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) int key_size, int value_size, int max_entries,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) __u32 map_flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) struct bpf_create_map_attr map_attr = {};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) map_attr.name = name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) map_attr.map_type = map_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) map_attr.map_flags = map_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) map_attr.key_size = key_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) map_attr.value_size = value_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) map_attr.max_entries = max_entries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) return bpf_create_map_xattr(&map_attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) int bpf_create_map_in_map_node(enum bpf_map_type map_type, const char *name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) int key_size, int inner_map_fd, int max_entries,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) __u32 map_flags, int node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) union bpf_attr attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) memset(&attr, '\0', sizeof(attr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) attr.map_type = map_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) attr.key_size = key_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) attr.value_size = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) attr.inner_map_fd = inner_map_fd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) attr.max_entries = max_entries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) attr.map_flags = map_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) if (name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) memcpy(attr.map_name, name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) min(strlen(name), BPF_OBJ_NAME_LEN - 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) if (node >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) attr.map_flags |= BPF_F_NUMA_NODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) attr.numa_node = node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) return sys_bpf(BPF_MAP_CREATE, &attr, sizeof(attr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) int bpf_create_map_in_map(enum bpf_map_type map_type, const char *name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) int key_size, int inner_map_fd, int max_entries,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) __u32 map_flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) return bpf_create_map_in_map_node(map_type, name, key_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) inner_map_fd, max_entries, map_flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) static void *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) alloc_zero_tailing_info(const void *orecord, __u32 cnt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) __u32 actual_rec_size, __u32 expected_rec_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) __u64 info_len = (__u64)actual_rec_size * cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) void *info, *nrecord;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) info = malloc(info_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) if (!info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) /* zero out bytes kernel does not understand */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) nrecord = info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) for (i = 0; i < cnt; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) memcpy(nrecord, orecord, expected_rec_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) memset(nrecord + expected_rec_size, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) actual_rec_size - expected_rec_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) orecord += actual_rec_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) nrecord += actual_rec_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) return info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) int bpf_load_program_xattr(const struct bpf_load_program_attr *load_attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) char *log_buf, size_t log_buf_sz)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) void *finfo = NULL, *linfo = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) union bpf_attr attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) __u32 log_level;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) int fd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) if (!load_attr || !log_buf != !log_buf_sz)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) log_level = load_attr->log_level;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) if (log_level > (4 | 2 | 1) || (log_level && !log_buf))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) memset(&attr, 0, sizeof(attr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) attr.prog_type = load_attr->prog_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) attr.expected_attach_type = load_attr->expected_attach_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) if (attr.prog_type == BPF_PROG_TYPE_STRUCT_OPS ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) attr.prog_type == BPF_PROG_TYPE_LSM) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) attr.attach_btf_id = load_attr->attach_btf_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) } else if (attr.prog_type == BPF_PROG_TYPE_TRACING ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) attr.prog_type == BPF_PROG_TYPE_EXT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) attr.attach_btf_id = load_attr->attach_btf_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) attr.attach_prog_fd = load_attr->attach_prog_fd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) attr.prog_ifindex = load_attr->prog_ifindex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) attr.kern_version = load_attr->kern_version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) attr.insn_cnt = (__u32)load_attr->insns_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) attr.insns = ptr_to_u64(load_attr->insns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) attr.license = ptr_to_u64(load_attr->license);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) attr.log_level = log_level;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) if (log_level) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) attr.log_buf = ptr_to_u64(log_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) attr.log_size = log_buf_sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) attr.log_buf = ptr_to_u64(NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) attr.log_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) attr.prog_btf_fd = load_attr->prog_btf_fd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) attr.func_info_rec_size = load_attr->func_info_rec_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) attr.func_info_cnt = load_attr->func_info_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) attr.func_info = ptr_to_u64(load_attr->func_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) attr.line_info_rec_size = load_attr->line_info_rec_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) attr.line_info_cnt = load_attr->line_info_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) attr.line_info = ptr_to_u64(load_attr->line_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) if (load_attr->name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) memcpy(attr.prog_name, load_attr->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) min(strlen(load_attr->name), BPF_OBJ_NAME_LEN - 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) attr.prog_flags = load_attr->prog_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) fd = sys_bpf_prog_load(&attr, sizeof(attr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) if (fd >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) return fd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) /* After bpf_prog_load, the kernel may modify certain attributes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) * to give user space a hint how to deal with loading failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) * Check to see whether we can make some changes and load again.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) while (errno == E2BIG && (!finfo || !linfo)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) if (!finfo && attr.func_info_cnt &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) attr.func_info_rec_size < load_attr->func_info_rec_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) /* try with corrected func info records */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) finfo = alloc_zero_tailing_info(load_attr->func_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) load_attr->func_info_cnt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) load_attr->func_info_rec_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) attr.func_info_rec_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) if (!finfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) attr.func_info = ptr_to_u64(finfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) attr.func_info_rec_size = load_attr->func_info_rec_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) } else if (!linfo && attr.line_info_cnt &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) attr.line_info_rec_size <
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) load_attr->line_info_rec_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) linfo = alloc_zero_tailing_info(load_attr->line_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) load_attr->line_info_cnt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) load_attr->line_info_rec_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) attr.line_info_rec_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) if (!linfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) attr.line_info = ptr_to_u64(linfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) attr.line_info_rec_size = load_attr->line_info_rec_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) fd = sys_bpf_prog_load(&attr, sizeof(attr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) if (fd >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) if (log_level || !log_buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) /* Try again with log */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) attr.log_buf = ptr_to_u64(log_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) attr.log_size = log_buf_sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) attr.log_level = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) log_buf[0] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) fd = sys_bpf_prog_load(&attr, sizeof(attr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) free(finfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) free(linfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) return fd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) int bpf_load_program(enum bpf_prog_type type, const struct bpf_insn *insns,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) size_t insns_cnt, const char *license,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) __u32 kern_version, char *log_buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) size_t log_buf_sz)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) struct bpf_load_program_attr load_attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) memset(&load_attr, 0, sizeof(struct bpf_load_program_attr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) load_attr.prog_type = type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) load_attr.expected_attach_type = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) load_attr.name = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) load_attr.insns = insns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) load_attr.insns_cnt = insns_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) load_attr.license = license;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) load_attr.kern_version = kern_version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) return bpf_load_program_xattr(&load_attr, log_buf, log_buf_sz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) int bpf_verify_program(enum bpf_prog_type type, const struct bpf_insn *insns,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) size_t insns_cnt, __u32 prog_flags, const char *license,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) __u32 kern_version, char *log_buf, size_t log_buf_sz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) int log_level)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) union bpf_attr attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) memset(&attr, 0, sizeof(attr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) attr.prog_type = type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) attr.insn_cnt = (__u32)insns_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) attr.insns = ptr_to_u64(insns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) attr.license = ptr_to_u64(license);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) attr.log_buf = ptr_to_u64(log_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) attr.log_size = log_buf_sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) attr.log_level = log_level;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) log_buf[0] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) attr.kern_version = kern_version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) attr.prog_flags = prog_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) return sys_bpf_prog_load(&attr, sizeof(attr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) int bpf_map_update_elem(int fd, const void *key, const void *value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) __u64 flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) union bpf_attr attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) memset(&attr, 0, sizeof(attr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) attr.map_fd = fd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) attr.key = ptr_to_u64(key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) attr.value = ptr_to_u64(value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) attr.flags = flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) return sys_bpf(BPF_MAP_UPDATE_ELEM, &attr, sizeof(attr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) int bpf_map_lookup_elem(int fd, const void *key, void *value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) union bpf_attr attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) memset(&attr, 0, sizeof(attr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) attr.map_fd = fd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) attr.key = ptr_to_u64(key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) attr.value = ptr_to_u64(value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) return sys_bpf(BPF_MAP_LOOKUP_ELEM, &attr, sizeof(attr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) int bpf_map_lookup_elem_flags(int fd, const void *key, void *value, __u64 flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) union bpf_attr attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) memset(&attr, 0, sizeof(attr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) attr.map_fd = fd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) attr.key = ptr_to_u64(key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) attr.value = ptr_to_u64(value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) attr.flags = flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) return sys_bpf(BPF_MAP_LOOKUP_ELEM, &attr, sizeof(attr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) int bpf_map_lookup_and_delete_elem(int fd, const void *key, void *value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) union bpf_attr attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) memset(&attr, 0, sizeof(attr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) attr.map_fd = fd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) attr.key = ptr_to_u64(key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) attr.value = ptr_to_u64(value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) return sys_bpf(BPF_MAP_LOOKUP_AND_DELETE_ELEM, &attr, sizeof(attr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) int bpf_map_delete_elem(int fd, const void *key)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) union bpf_attr attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) memset(&attr, 0, sizeof(attr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) attr.map_fd = fd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) attr.key = ptr_to_u64(key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) return sys_bpf(BPF_MAP_DELETE_ELEM, &attr, sizeof(attr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) int bpf_map_get_next_key(int fd, const void *key, void *next_key)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) union bpf_attr attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) memset(&attr, 0, sizeof(attr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) attr.map_fd = fd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) attr.key = ptr_to_u64(key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) attr.next_key = ptr_to_u64(next_key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) return sys_bpf(BPF_MAP_GET_NEXT_KEY, &attr, sizeof(attr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) int bpf_map_freeze(int fd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) union bpf_attr attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) memset(&attr, 0, sizeof(attr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) attr.map_fd = fd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) return sys_bpf(BPF_MAP_FREEZE, &attr, sizeof(attr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) static int bpf_map_batch_common(int cmd, int fd, void *in_batch,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) void *out_batch, void *keys, void *values,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) __u32 *count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) const struct bpf_map_batch_opts *opts)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) union bpf_attr attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) if (!OPTS_VALID(opts, bpf_map_batch_opts))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) memset(&attr, 0, sizeof(attr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) attr.batch.map_fd = fd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) attr.batch.in_batch = ptr_to_u64(in_batch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) attr.batch.out_batch = ptr_to_u64(out_batch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) attr.batch.keys = ptr_to_u64(keys);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) attr.batch.values = ptr_to_u64(values);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) attr.batch.count = *count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) attr.batch.elem_flags = OPTS_GET(opts, elem_flags, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) attr.batch.flags = OPTS_GET(opts, flags, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) ret = sys_bpf(cmd, &attr, sizeof(attr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) *count = attr.batch.count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) int bpf_map_delete_batch(int fd, void *keys, __u32 *count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) const struct bpf_map_batch_opts *opts)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) return bpf_map_batch_common(BPF_MAP_DELETE_BATCH, fd, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) NULL, keys, NULL, count, opts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) int bpf_map_lookup_batch(int fd, void *in_batch, void *out_batch, void *keys,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) void *values, __u32 *count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) const struct bpf_map_batch_opts *opts)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) return bpf_map_batch_common(BPF_MAP_LOOKUP_BATCH, fd, in_batch,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) out_batch, keys, values, count, opts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) int bpf_map_lookup_and_delete_batch(int fd, void *in_batch, void *out_batch,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) void *keys, void *values, __u32 *count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) const struct bpf_map_batch_opts *opts)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) return bpf_map_batch_common(BPF_MAP_LOOKUP_AND_DELETE_BATCH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) fd, in_batch, out_batch, keys, values,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) count, opts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) int bpf_map_update_batch(int fd, void *keys, void *values, __u32 *count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) const struct bpf_map_batch_opts *opts)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) return bpf_map_batch_common(BPF_MAP_UPDATE_BATCH, fd, NULL, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) keys, values, count, opts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) int bpf_obj_pin(int fd, const char *pathname)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) union bpf_attr attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) memset(&attr, 0, sizeof(attr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) attr.pathname = ptr_to_u64((void *)pathname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) attr.bpf_fd = fd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) return sys_bpf(BPF_OBJ_PIN, &attr, sizeof(attr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) int bpf_obj_get(const char *pathname)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) union bpf_attr attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) memset(&attr, 0, sizeof(attr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) attr.pathname = ptr_to_u64((void *)pathname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) return sys_bpf(BPF_OBJ_GET, &attr, sizeof(attr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) int bpf_prog_attach(int prog_fd, int target_fd, enum bpf_attach_type type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) unsigned int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) DECLARE_LIBBPF_OPTS(bpf_prog_attach_opts, opts,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) .flags = flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) return bpf_prog_attach_xattr(prog_fd, target_fd, type, &opts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) int bpf_prog_attach_xattr(int prog_fd, int target_fd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) enum bpf_attach_type type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) const struct bpf_prog_attach_opts *opts)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) union bpf_attr attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) if (!OPTS_VALID(opts, bpf_prog_attach_opts))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) memset(&attr, 0, sizeof(attr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) attr.target_fd = target_fd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) attr.attach_bpf_fd = prog_fd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) attr.attach_type = type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) attr.attach_flags = OPTS_GET(opts, flags, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) attr.replace_bpf_fd = OPTS_GET(opts, replace_prog_fd, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) return sys_bpf(BPF_PROG_ATTACH, &attr, sizeof(attr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) int bpf_prog_detach(int target_fd, enum bpf_attach_type type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) union bpf_attr attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) memset(&attr, 0, sizeof(attr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) attr.target_fd = target_fd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) attr.attach_type = type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) return sys_bpf(BPF_PROG_DETACH, &attr, sizeof(attr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) int bpf_prog_detach2(int prog_fd, int target_fd, enum bpf_attach_type type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) union bpf_attr attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) memset(&attr, 0, sizeof(attr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) attr.target_fd = target_fd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) attr.attach_bpf_fd = prog_fd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) attr.attach_type = type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) return sys_bpf(BPF_PROG_DETACH, &attr, sizeof(attr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) int bpf_link_create(int prog_fd, int target_fd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) enum bpf_attach_type attach_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) const struct bpf_link_create_opts *opts)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) __u32 target_btf_id, iter_info_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) union bpf_attr attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) if (!OPTS_VALID(opts, bpf_link_create_opts))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) iter_info_len = OPTS_GET(opts, iter_info_len, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) target_btf_id = OPTS_GET(opts, target_btf_id, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) if (iter_info_len && target_btf_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) memset(&attr, 0, sizeof(attr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) attr.link_create.prog_fd = prog_fd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) attr.link_create.target_fd = target_fd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) attr.link_create.attach_type = attach_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) attr.link_create.flags = OPTS_GET(opts, flags, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) if (iter_info_len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) attr.link_create.iter_info =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) ptr_to_u64(OPTS_GET(opts, iter_info, (void *)0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) attr.link_create.iter_info_len = iter_info_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) } else if (target_btf_id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) attr.link_create.target_btf_id = target_btf_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) return sys_bpf(BPF_LINK_CREATE, &attr, sizeof(attr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) int bpf_link_detach(int link_fd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) union bpf_attr attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) memset(&attr, 0, sizeof(attr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) attr.link_detach.link_fd = link_fd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) return sys_bpf(BPF_LINK_DETACH, &attr, sizeof(attr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) int bpf_link_update(int link_fd, int new_prog_fd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) const struct bpf_link_update_opts *opts)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) union bpf_attr attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) if (!OPTS_VALID(opts, bpf_link_update_opts))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) memset(&attr, 0, sizeof(attr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) attr.link_update.link_fd = link_fd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) attr.link_update.new_prog_fd = new_prog_fd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) attr.link_update.flags = OPTS_GET(opts, flags, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) attr.link_update.old_prog_fd = OPTS_GET(opts, old_prog_fd, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) return sys_bpf(BPF_LINK_UPDATE, &attr, sizeof(attr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) int bpf_iter_create(int link_fd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) union bpf_attr attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) memset(&attr, 0, sizeof(attr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) attr.iter_create.link_fd = link_fd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) return sys_bpf(BPF_ITER_CREATE, &attr, sizeof(attr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) int bpf_prog_query(int target_fd, enum bpf_attach_type type, __u32 query_flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) __u32 *attach_flags, __u32 *prog_ids, __u32 *prog_cnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) union bpf_attr attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) memset(&attr, 0, sizeof(attr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) attr.query.target_fd = target_fd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) attr.query.attach_type = type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) attr.query.query_flags = query_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) attr.query.prog_cnt = *prog_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) attr.query.prog_ids = ptr_to_u64(prog_ids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) ret = sys_bpf(BPF_PROG_QUERY, &attr, sizeof(attr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) if (attach_flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) *attach_flags = attr.query.attach_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) *prog_cnt = attr.query.prog_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) int bpf_prog_test_run(int prog_fd, int repeat, void *data, __u32 size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) void *data_out, __u32 *size_out, __u32 *retval,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) __u32 *duration)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) union bpf_attr attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) memset(&attr, 0, sizeof(attr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) attr.test.prog_fd = prog_fd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) attr.test.data_in = ptr_to_u64(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) attr.test.data_out = ptr_to_u64(data_out);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) attr.test.data_size_in = size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) attr.test.repeat = repeat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) ret = sys_bpf(BPF_PROG_TEST_RUN, &attr, sizeof(attr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) if (size_out)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) *size_out = attr.test.data_size_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) if (retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) *retval = attr.test.retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) if (duration)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) *duration = attr.test.duration;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) int bpf_prog_test_run_xattr(struct bpf_prog_test_run_attr *test_attr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) union bpf_attr attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) if (!test_attr->data_out && test_attr->data_size_out > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) memset(&attr, 0, sizeof(attr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) attr.test.prog_fd = test_attr->prog_fd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) attr.test.data_in = ptr_to_u64(test_attr->data_in);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) attr.test.data_out = ptr_to_u64(test_attr->data_out);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) attr.test.data_size_in = test_attr->data_size_in;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) attr.test.data_size_out = test_attr->data_size_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) attr.test.ctx_in = ptr_to_u64(test_attr->ctx_in);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) attr.test.ctx_out = ptr_to_u64(test_attr->ctx_out);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) attr.test.ctx_size_in = test_attr->ctx_size_in;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) attr.test.ctx_size_out = test_attr->ctx_size_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) attr.test.repeat = test_attr->repeat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) ret = sys_bpf(BPF_PROG_TEST_RUN, &attr, sizeof(attr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) test_attr->data_size_out = attr.test.data_size_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) test_attr->ctx_size_out = attr.test.ctx_size_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) test_attr->retval = attr.test.retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) test_attr->duration = attr.test.duration;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) int bpf_prog_test_run_opts(int prog_fd, struct bpf_test_run_opts *opts)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) union bpf_attr attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) if (!OPTS_VALID(opts, bpf_test_run_opts))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) memset(&attr, 0, sizeof(attr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) attr.test.prog_fd = prog_fd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) attr.test.cpu = OPTS_GET(opts, cpu, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) attr.test.flags = OPTS_GET(opts, flags, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) attr.test.repeat = OPTS_GET(opts, repeat, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) attr.test.duration = OPTS_GET(opts, duration, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) attr.test.ctx_size_in = OPTS_GET(opts, ctx_size_in, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) attr.test.ctx_size_out = OPTS_GET(opts, ctx_size_out, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) attr.test.data_size_in = OPTS_GET(opts, data_size_in, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) attr.test.data_size_out = OPTS_GET(opts, data_size_out, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) attr.test.ctx_in = ptr_to_u64(OPTS_GET(opts, ctx_in, NULL));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) attr.test.ctx_out = ptr_to_u64(OPTS_GET(opts, ctx_out, NULL));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) attr.test.data_in = ptr_to_u64(OPTS_GET(opts, data_in, NULL));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) attr.test.data_out = ptr_to_u64(OPTS_GET(opts, data_out, NULL));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) ret = sys_bpf(BPF_PROG_TEST_RUN, &attr, sizeof(attr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) OPTS_SET(opts, data_size_out, attr.test.data_size_out);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) OPTS_SET(opts, ctx_size_out, attr.test.ctx_size_out);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) OPTS_SET(opts, duration, attr.test.duration);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) OPTS_SET(opts, retval, attr.test.retval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) static int bpf_obj_get_next_id(__u32 start_id, __u32 *next_id, int cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) union bpf_attr attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) memset(&attr, 0, sizeof(attr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) attr.start_id = start_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) err = sys_bpf(cmd, &attr, sizeof(attr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) if (!err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) *next_id = attr.next_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) int bpf_prog_get_next_id(__u32 start_id, __u32 *next_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) return bpf_obj_get_next_id(start_id, next_id, BPF_PROG_GET_NEXT_ID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) int bpf_map_get_next_id(__u32 start_id, __u32 *next_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) return bpf_obj_get_next_id(start_id, next_id, BPF_MAP_GET_NEXT_ID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) int bpf_btf_get_next_id(__u32 start_id, __u32 *next_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) return bpf_obj_get_next_id(start_id, next_id, BPF_BTF_GET_NEXT_ID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) int bpf_link_get_next_id(__u32 start_id, __u32 *next_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) return bpf_obj_get_next_id(start_id, next_id, BPF_LINK_GET_NEXT_ID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) int bpf_prog_get_fd_by_id(__u32 id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) union bpf_attr attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) memset(&attr, 0, sizeof(attr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) attr.prog_id = id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) return sys_bpf(BPF_PROG_GET_FD_BY_ID, &attr, sizeof(attr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) int bpf_map_get_fd_by_id(__u32 id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) union bpf_attr attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) memset(&attr, 0, sizeof(attr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) attr.map_id = id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) return sys_bpf(BPF_MAP_GET_FD_BY_ID, &attr, sizeof(attr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) int bpf_btf_get_fd_by_id(__u32 id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) union bpf_attr attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) memset(&attr, 0, sizeof(attr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) attr.btf_id = id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) return sys_bpf(BPF_BTF_GET_FD_BY_ID, &attr, sizeof(attr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) int bpf_link_get_fd_by_id(__u32 id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) union bpf_attr attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) memset(&attr, 0, sizeof(attr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) attr.link_id = id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) return sys_bpf(BPF_LINK_GET_FD_BY_ID, &attr, sizeof(attr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) int bpf_obj_get_info_by_fd(int bpf_fd, void *info, __u32 *info_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) union bpf_attr attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) memset(&attr, 0, sizeof(attr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) attr.info.bpf_fd = bpf_fd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) attr.info.info_len = *info_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) attr.info.info = ptr_to_u64(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) err = sys_bpf(BPF_OBJ_GET_INFO_BY_FD, &attr, sizeof(attr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) if (!err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) *info_len = attr.info.info_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) int bpf_raw_tracepoint_open(const char *name, int prog_fd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) union bpf_attr attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) memset(&attr, 0, sizeof(attr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) attr.raw_tracepoint.name = ptr_to_u64(name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) attr.raw_tracepoint.prog_fd = prog_fd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) return sys_bpf(BPF_RAW_TRACEPOINT_OPEN, &attr, sizeof(attr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) int bpf_load_btf(const void *btf, __u32 btf_size, char *log_buf, __u32 log_buf_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) bool do_log)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) union bpf_attr attr = {};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) int fd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) attr.btf = ptr_to_u64(btf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) attr.btf_size = btf_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) retry:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) if (do_log && log_buf && log_buf_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) attr.btf_log_level = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) attr.btf_log_size = log_buf_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) attr.btf_log_buf = ptr_to_u64(log_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) fd = sys_bpf(BPF_BTF_LOAD, &attr, sizeof(attr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) if (fd == -1 && !do_log && log_buf && log_buf_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) do_log = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) goto retry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) return fd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) int bpf_task_fd_query(int pid, int fd, __u32 flags, char *buf, __u32 *buf_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) __u32 *prog_id, __u32 *fd_type, __u64 *probe_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) __u64 *probe_addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) union bpf_attr attr = {};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) attr.task_fd_query.pid = pid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) attr.task_fd_query.fd = fd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) attr.task_fd_query.flags = flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) attr.task_fd_query.buf = ptr_to_u64(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) attr.task_fd_query.buf_len = *buf_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) err = sys_bpf(BPF_TASK_FD_QUERY, &attr, sizeof(attr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) *buf_len = attr.task_fd_query.buf_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) *prog_id = attr.task_fd_query.prog_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) *fd_type = attr.task_fd_query.fd_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) *probe_offset = attr.task_fd_query.probe_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) *probe_addr = attr.task_fd_query.probe_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) int bpf_enable_stats(enum bpf_stats_type type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) union bpf_attr attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) memset(&attr, 0, sizeof(attr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) attr.enable_stats.type = type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) return sys_bpf(BPF_ENABLE_STATS, &attr, sizeof(attr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) int bpf_prog_bind_map(int prog_fd, int map_fd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) const struct bpf_prog_bind_opts *opts)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) union bpf_attr attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) if (!OPTS_VALID(opts, bpf_prog_bind_opts))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) memset(&attr, 0, sizeof(attr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) attr.prog_bind_map.prog_fd = prog_fd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) attr.prog_bind_map.map_fd = map_fd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) attr.prog_bind_map.flags = OPTS_GET(opts, flags, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) return sys_bpf(BPF_PROG_BIND_MAP, &attr, sizeof(attr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) }