Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags   |
^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) }