Commit | Line | Data |
---|---|---|
1bc38b8f | 1 | // SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) |
6061a3d6 | 2 | |
e3ed2fef WN |
3 | /* |
4 | * common eBPF ELF operations. | |
5 | * | |
6 | * Copyright (C) 2013-2015 Alexei Starovoitov <ast@kernel.org> | |
7 | * Copyright (C) 2015 Wang Nan <wangnan0@huawei.com> | |
8 | * Copyright (C) 2015 Huawei Inc. | |
203d1cac WN |
9 | * |
10 | * This program is free software; you can redistribute it and/or | |
11 | * modify it under the terms of the GNU Lesser General Public | |
12 | * License as published by the Free Software Foundation; | |
13 | * version 2.1 of the License (not later!) | |
14 | * | |
15 | * This program is distributed in the hope that it will be useful, | |
16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
18 | * GNU Lesser General Public License for more details. | |
19 | * | |
20 | * You should have received a copy of the GNU Lesser General Public | |
21 | * License along with this program; if not, see <http://www.gnu.org/licenses> | |
e3ed2fef WN |
22 | */ |
23 | ||
24 | #include <stdlib.h> | |
25 | #include <memory.h> | |
26 | #include <unistd.h> | |
27 | #include <asm/unistd.h> | |
28 | #include <linux/bpf.h> | |
29 | #include "bpf.h" | |
949abbe8 | 30 | #include "libbpf.h" |
949abbe8 | 31 | #include <errno.h> |
e3ed2fef WN |
32 | |
33 | /* | |
03671057 | 34 | * When building perf, unistd.h is overridden. __NR_bpf is |
8f9e05fb | 35 | * required to be defined explicitly. |
e3ed2fef WN |
36 | */ |
37 | #ifndef __NR_bpf | |
38 | # if defined(__i386__) | |
39 | # define __NR_bpf 357 | |
40 | # elif defined(__x86_64__) | |
41 | # define __NR_bpf 321 | |
42 | # elif defined(__aarch64__) | |
43 | # define __NR_bpf 280 | |
b0c47807 DM |
44 | # elif defined(__sparc__) |
45 | # define __NR_bpf 349 | |
bad1926d DB |
46 | # elif defined(__s390__) |
47 | # define __NR_bpf 351 | |
e3ed2fef WN |
48 | # else |
49 | # error __NR_bpf not defined. libbpf does not support your arch. | |
50 | # endif | |
51 | #endif | |
52 | ||
949abbe8 | 53 | #ifndef min |
88cda1c9 | 54 | #define min(x, y) ((x) < (y) ? (x) : (y)) |
949abbe8 | 55 | #endif |
88cda1c9 | 56 | |
cdc6a4ba | 57 | static inline __u64 ptr_to_u64(const void *ptr) |
7bf98369 WN |
58 | { |
59 | return (__u64) (unsigned long) ptr; | |
60 | } | |
61 | ||
cdc6a4ba MS |
62 | static inline int sys_bpf(enum bpf_cmd cmd, union bpf_attr *attr, |
63 | unsigned int size) | |
e3ed2fef WN |
64 | { |
65 | return syscall(__NR_bpf, cmd, attr, size); | |
66 | } | |
67 | ||
8a138aed | 68 | int bpf_create_map_xattr(const struct bpf_create_map_attr *create_attr) |
e3ed2fef | 69 | { |
8a138aed | 70 | __u32 name_len = create_attr->name ? strlen(create_attr->name) : 0; |
e3ed2fef WN |
71 | union bpf_attr attr; |
72 | ||
73 | memset(&attr, '\0', sizeof(attr)); | |
74 | ||
8a138aed MKL |
75 | attr.map_type = create_attr->map_type; |
76 | attr.key_size = create_attr->key_size; | |
77 | attr.value_size = create_attr->value_size; | |
78 | attr.max_entries = create_attr->max_entries; | |
79 | attr.map_flags = create_attr->map_flags; | |
80 | memcpy(attr.map_name, create_attr->name, | |
81 | min(name_len, BPF_OBJ_NAME_LEN - 1)); | |
82 | attr.numa_node = create_attr->numa_node; | |
83 | attr.btf_fd = create_attr->btf_fd; | |
61746dbe MKL |
84 | attr.btf_key_type_id = create_attr->btf_key_type_id; |
85 | attr.btf_value_type_id = create_attr->btf_value_type_id; | |
f0307a7e | 86 | attr.map_ifindex = create_attr->map_ifindex; |
91134d84 | 87 | attr.inner_map_fd = create_attr->inner_map_fd; |
8a138aed MKL |
88 | |
89 | return sys_bpf(BPF_MAP_CREATE, &attr, sizeof(attr)); | |
90 | } | |
88cda1c9 | 91 | |
8a138aed MKL |
92 | int bpf_create_map_node(enum bpf_map_type map_type, const char *name, |
93 | int key_size, int value_size, int max_entries, | |
94 | __u32 map_flags, int node) | |
95 | { | |
96 | struct bpf_create_map_attr map_attr = {}; | |
97 | ||
98 | map_attr.name = name; | |
99 | map_attr.map_type = map_type; | |
100 | map_attr.map_flags = map_flags; | |
101 | map_attr.key_size = key_size; | |
102 | map_attr.value_size = value_size; | |
103 | map_attr.max_entries = max_entries; | |
ad17d0e6 | 104 | if (node >= 0) { |
8a138aed MKL |
105 | map_attr.numa_node = node; |
106 | map_attr.map_flags |= BPF_F_NUMA_NODE; | |
ad17d0e6 | 107 | } |
e3ed2fef | 108 | |
8a138aed | 109 | return bpf_create_map_xattr(&map_attr); |
e3ed2fef | 110 | } |
7bf98369 | 111 | |
ad17d0e6 MKL |
112 | int bpf_create_map(enum bpf_map_type map_type, int key_size, |
113 | int value_size, int max_entries, __u32 map_flags) | |
114 | { | |
8a138aed MKL |
115 | struct bpf_create_map_attr map_attr = {}; |
116 | ||
117 | map_attr.map_type = map_type; | |
118 | map_attr.map_flags = map_flags; | |
119 | map_attr.key_size = key_size; | |
120 | map_attr.value_size = value_size; | |
121 | map_attr.max_entries = max_entries; | |
122 | ||
123 | return bpf_create_map_xattr(&map_attr); | |
ad17d0e6 MKL |
124 | } |
125 | ||
88cda1c9 MKL |
126 | int bpf_create_map_name(enum bpf_map_type map_type, const char *name, |
127 | int key_size, int value_size, int max_entries, | |
128 | __u32 map_flags) | |
129 | { | |
8a138aed MKL |
130 | struct bpf_create_map_attr map_attr = {}; |
131 | ||
132 | map_attr.name = name; | |
133 | map_attr.map_type = map_type; | |
134 | map_attr.map_flags = map_flags; | |
135 | map_attr.key_size = key_size; | |
136 | map_attr.value_size = value_size; | |
137 | map_attr.max_entries = max_entries; | |
138 | ||
139 | return bpf_create_map_xattr(&map_attr); | |
88cda1c9 MKL |
140 | } |
141 | ||
142 | int bpf_create_map_in_map_node(enum bpf_map_type map_type, const char *name, | |
143 | int key_size, int inner_map_fd, int max_entries, | |
ad17d0e6 | 144 | __u32 map_flags, int node) |
fb30d4b7 | 145 | { |
88cda1c9 | 146 | __u32 name_len = name ? strlen(name) : 0; |
fb30d4b7 MKL |
147 | union bpf_attr attr; |
148 | ||
149 | memset(&attr, '\0', sizeof(attr)); | |
150 | ||
151 | attr.map_type = map_type; | |
152 | attr.key_size = key_size; | |
153 | attr.value_size = 4; | |
154 | attr.inner_map_fd = inner_map_fd; | |
155 | attr.max_entries = max_entries; | |
156 | attr.map_flags = map_flags; | |
88cda1c9 MKL |
157 | memcpy(attr.map_name, name, min(name_len, BPF_OBJ_NAME_LEN - 1)); |
158 | ||
ad17d0e6 MKL |
159 | if (node >= 0) { |
160 | attr.map_flags |= BPF_F_NUMA_NODE; | |
161 | attr.numa_node = node; | |
162 | } | |
fb30d4b7 MKL |
163 | |
164 | return sys_bpf(BPF_MAP_CREATE, &attr, sizeof(attr)); | |
165 | } | |
166 | ||
88cda1c9 MKL |
167 | int bpf_create_map_in_map(enum bpf_map_type map_type, const char *name, |
168 | int key_size, int inner_map_fd, int max_entries, | |
169 | __u32 map_flags) | |
ad17d0e6 | 170 | { |
88cda1c9 MKL |
171 | return bpf_create_map_in_map_node(map_type, name, key_size, |
172 | inner_map_fd, max_entries, map_flags, | |
173 | -1); | |
ad17d0e6 MKL |
174 | } |
175 | ||
d7be143b AI |
176 | int bpf_load_program_xattr(const struct bpf_load_program_attr *load_attr, |
177 | char *log_buf, size_t log_buf_sz) | |
7bf98369 | 178 | { |
7bf98369 | 179 | union bpf_attr attr; |
d7be143b AI |
180 | __u32 name_len; |
181 | int fd; | |
182 | ||
183 | if (!load_attr) | |
184 | return -EINVAL; | |
185 | ||
186 | name_len = load_attr->name ? strlen(load_attr->name) : 0; | |
7bf98369 WN |
187 | |
188 | bzero(&attr, sizeof(attr)); | |
d7be143b AI |
189 | attr.prog_type = load_attr->prog_type; |
190 | attr.expected_attach_type = load_attr->expected_attach_type; | |
191 | attr.insn_cnt = (__u32)load_attr->insns_cnt; | |
192 | attr.insns = ptr_to_u64(load_attr->insns); | |
193 | attr.license = ptr_to_u64(load_attr->license); | |
7bf98369 WN |
194 | attr.log_buf = ptr_to_u64(NULL); |
195 | attr.log_size = 0; | |
196 | attr.log_level = 0; | |
d7be143b | 197 | attr.kern_version = load_attr->kern_version; |
f0307a7e | 198 | attr.prog_ifindex = load_attr->prog_ifindex; |
d7be143b AI |
199 | memcpy(attr.prog_name, load_attr->name, |
200 | min(name_len, BPF_OBJ_NAME_LEN - 1)); | |
7bf98369 WN |
201 | |
202 | fd = sys_bpf(BPF_PROG_LOAD, &attr, sizeof(attr)); | |
203 | if (fd >= 0 || !log_buf || !log_buf_sz) | |
204 | return fd; | |
205 | ||
206 | /* Try again with log */ | |
207 | attr.log_buf = ptr_to_u64(log_buf); | |
208 | attr.log_size = log_buf_sz; | |
209 | attr.log_level = 1; | |
210 | log_buf[0] = 0; | |
211 | return sys_bpf(BPF_PROG_LOAD, &attr, sizeof(attr)); | |
212 | } | |
43798bf3 | 213 | |
88cda1c9 MKL |
214 | int bpf_load_program(enum bpf_prog_type type, const struct bpf_insn *insns, |
215 | size_t insns_cnt, const char *license, | |
216 | __u32 kern_version, char *log_buf, | |
217 | size_t log_buf_sz) | |
218 | { | |
d7be143b AI |
219 | struct bpf_load_program_attr load_attr; |
220 | ||
221 | memset(&load_attr, 0, sizeof(struct bpf_load_program_attr)); | |
222 | load_attr.prog_type = type; | |
223 | load_attr.expected_attach_type = 0; | |
224 | load_attr.name = NULL; | |
225 | load_attr.insns = insns; | |
226 | load_attr.insns_cnt = insns_cnt; | |
227 | load_attr.license = license; | |
228 | load_attr.kern_version = kern_version; | |
229 | ||
230 | return bpf_load_program_xattr(&load_attr, log_buf, log_buf_sz); | |
88cda1c9 MKL |
231 | } |
232 | ||
91045f5e DM |
233 | int bpf_verify_program(enum bpf_prog_type type, const struct bpf_insn *insns, |
234 | size_t insns_cnt, int strict_alignment, | |
235 | const char *license, __u32 kern_version, | |
d6554904 | 236 | char *log_buf, size_t log_buf_sz, int log_level) |
91045f5e DM |
237 | { |
238 | union bpf_attr attr; | |
239 | ||
240 | bzero(&attr, sizeof(attr)); | |
241 | attr.prog_type = type; | |
242 | attr.insn_cnt = (__u32)insns_cnt; | |
243 | attr.insns = ptr_to_u64(insns); | |
244 | attr.license = ptr_to_u64(license); | |
245 | attr.log_buf = ptr_to_u64(log_buf); | |
246 | attr.log_size = log_buf_sz; | |
d6554904 | 247 | attr.log_level = log_level; |
91045f5e DM |
248 | log_buf[0] = 0; |
249 | attr.kern_version = kern_version; | |
250 | attr.prog_flags = strict_alignment ? BPF_F_STRICT_ALIGNMENT : 0; | |
251 | ||
252 | return sys_bpf(BPF_PROG_LOAD, &attr, sizeof(attr)); | |
253 | } | |
254 | ||
10ecc728 | 255 | int bpf_map_update_elem(int fd, const void *key, const void *value, |
83d994d0 | 256 | __u64 flags) |
43798bf3 HK |
257 | { |
258 | union bpf_attr attr; | |
259 | ||
260 | bzero(&attr, sizeof(attr)); | |
261 | attr.map_fd = fd; | |
262 | attr.key = ptr_to_u64(key); | |
263 | attr.value = ptr_to_u64(value); | |
264 | attr.flags = flags; | |
265 | ||
266 | return sys_bpf(BPF_MAP_UPDATE_ELEM, &attr, sizeof(attr)); | |
267 | } | |
9742da01 | 268 | |
e5ff7c40 | 269 | int bpf_map_lookup_elem(int fd, const void *key, void *value) |
9742da01 WN |
270 | { |
271 | union bpf_attr attr; | |
272 | ||
273 | bzero(&attr, sizeof(attr)); | |
274 | attr.map_fd = fd; | |
275 | attr.key = ptr_to_u64(key); | |
276 | attr.value = ptr_to_u64(value); | |
277 | ||
278 | return sys_bpf(BPF_MAP_LOOKUP_ELEM, &attr, sizeof(attr)); | |
279 | } | |
280 | ||
43b987d2 MV |
281 | int bpf_map_lookup_and_delete_elem(int fd, const void *key, void *value) |
282 | { | |
283 | union bpf_attr attr; | |
284 | ||
285 | bzero(&attr, sizeof(attr)); | |
286 | attr.map_fd = fd; | |
287 | attr.key = ptr_to_u64(key); | |
288 | attr.value = ptr_to_u64(value); | |
289 | ||
290 | return sys_bpf(BPF_MAP_LOOKUP_AND_DELETE_ELEM, &attr, sizeof(attr)); | |
291 | } | |
292 | ||
e58383b8 | 293 | int bpf_map_delete_elem(int fd, const void *key) |
9742da01 WN |
294 | { |
295 | union bpf_attr attr; | |
296 | ||
297 | bzero(&attr, sizeof(attr)); | |
298 | attr.map_fd = fd; | |
299 | attr.key = ptr_to_u64(key); | |
300 | ||
301 | return sys_bpf(BPF_MAP_DELETE_ELEM, &attr, sizeof(attr)); | |
302 | } | |
303 | ||
5f155c25 | 304 | int bpf_map_get_next_key(int fd, const void *key, void *next_key) |
9742da01 WN |
305 | { |
306 | union bpf_attr attr; | |
307 | ||
308 | bzero(&attr, sizeof(attr)); | |
309 | attr.map_fd = fd; | |
310 | attr.key = ptr_to_u64(key); | |
311 | attr.next_key = ptr_to_u64(next_key); | |
312 | ||
313 | return sys_bpf(BPF_MAP_GET_NEXT_KEY, &attr, sizeof(attr)); | |
314 | } | |
315 | ||
316 | int bpf_obj_pin(int fd, const char *pathname) | |
317 | { | |
318 | union bpf_attr attr; | |
319 | ||
320 | bzero(&attr, sizeof(attr)); | |
321 | attr.pathname = ptr_to_u64((void *)pathname); | |
322 | attr.bpf_fd = fd; | |
323 | ||
324 | return sys_bpf(BPF_OBJ_PIN, &attr, sizeof(attr)); | |
325 | } | |
326 | ||
327 | int bpf_obj_get(const char *pathname) | |
328 | { | |
329 | union bpf_attr attr; | |
330 | ||
331 | bzero(&attr, sizeof(attr)); | |
332 | attr.pathname = ptr_to_u64((void *)pathname); | |
333 | ||
334 | return sys_bpf(BPF_OBJ_GET, &attr, sizeof(attr)); | |
335 | } | |
5dc880de | 336 | |
464bc0fd JF |
337 | int bpf_prog_attach(int prog_fd, int target_fd, enum bpf_attach_type type, |
338 | unsigned int flags) | |
5dc880de JS |
339 | { |
340 | union bpf_attr attr; | |
341 | ||
342 | bzero(&attr, sizeof(attr)); | |
343 | attr.target_fd = target_fd; | |
464bc0fd | 344 | attr.attach_bpf_fd = prog_fd; |
5dc880de | 345 | attr.attach_type = type; |
7f677633 | 346 | attr.attach_flags = flags; |
5dc880de JS |
347 | |
348 | return sys_bpf(BPF_PROG_ATTACH, &attr, sizeof(attr)); | |
349 | } | |
350 | ||
351 | int bpf_prog_detach(int target_fd, enum bpf_attach_type type) | |
352 | { | |
353 | union bpf_attr attr; | |
354 | ||
355 | bzero(&attr, sizeof(attr)); | |
356 | attr.target_fd = target_fd; | |
357 | attr.attach_type = type; | |
358 | ||
359 | return sys_bpf(BPF_PROG_DETACH, &attr, sizeof(attr)); | |
360 | } | |
30848873 | 361 | |
244d20ef AS |
362 | int bpf_prog_detach2(int prog_fd, int target_fd, enum bpf_attach_type type) |
363 | { | |
364 | union bpf_attr attr; | |
365 | ||
366 | bzero(&attr, sizeof(attr)); | |
367 | attr.target_fd = target_fd; | |
368 | attr.attach_bpf_fd = prog_fd; | |
369 | attr.attach_type = type; | |
370 | ||
371 | return sys_bpf(BPF_PROG_DETACH, &attr, sizeof(attr)); | |
372 | } | |
373 | ||
5d0cbf9b AS |
374 | int bpf_prog_query(int target_fd, enum bpf_attach_type type, __u32 query_flags, |
375 | __u32 *attach_flags, __u32 *prog_ids, __u32 *prog_cnt) | |
376 | { | |
377 | union bpf_attr attr; | |
378 | int ret; | |
379 | ||
380 | bzero(&attr, sizeof(attr)); | |
381 | attr.query.target_fd = target_fd; | |
382 | attr.query.attach_type = type; | |
383 | attr.query.query_flags = query_flags; | |
384 | attr.query.prog_cnt = *prog_cnt; | |
385 | attr.query.prog_ids = ptr_to_u64(prog_ids); | |
386 | ||
387 | ret = sys_bpf(BPF_PROG_QUERY, &attr, sizeof(attr)); | |
388 | if (attach_flags) | |
389 | *attach_flags = attr.query.attach_flags; | |
390 | *prog_cnt = attr.query.prog_cnt; | |
391 | return ret; | |
392 | } | |
393 | ||
30848873 AS |
394 | int bpf_prog_test_run(int prog_fd, int repeat, void *data, __u32 size, |
395 | void *data_out, __u32 *size_out, __u32 *retval, | |
396 | __u32 *duration) | |
397 | { | |
398 | union bpf_attr attr; | |
399 | int ret; | |
400 | ||
401 | bzero(&attr, sizeof(attr)); | |
402 | attr.test.prog_fd = prog_fd; | |
403 | attr.test.data_in = ptr_to_u64(data); | |
404 | attr.test.data_out = ptr_to_u64(data_out); | |
405 | attr.test.data_size_in = size; | |
406 | attr.test.repeat = repeat; | |
407 | ||
408 | ret = sys_bpf(BPF_PROG_TEST_RUN, &attr, sizeof(attr)); | |
409 | if (size_out) | |
410 | *size_out = attr.test.data_size_out; | |
411 | if (retval) | |
412 | *retval = attr.test.retval; | |
413 | if (duration) | |
414 | *duration = attr.test.duration; | |
415 | return ret; | |
416 | } | |
95b9afd3 MKL |
417 | |
418 | int bpf_prog_get_next_id(__u32 start_id, __u32 *next_id) | |
419 | { | |
420 | union bpf_attr attr; | |
421 | int err; | |
422 | ||
423 | bzero(&attr, sizeof(attr)); | |
424 | attr.start_id = start_id; | |
425 | ||
426 | err = sys_bpf(BPF_PROG_GET_NEXT_ID, &attr, sizeof(attr)); | |
427 | if (!err) | |
428 | *next_id = attr.next_id; | |
429 | ||
430 | return err; | |
431 | } | |
432 | ||
433 | int bpf_map_get_next_id(__u32 start_id, __u32 *next_id) | |
434 | { | |
435 | union bpf_attr attr; | |
436 | int err; | |
437 | ||
438 | bzero(&attr, sizeof(attr)); | |
439 | attr.start_id = start_id; | |
440 | ||
441 | err = sys_bpf(BPF_MAP_GET_NEXT_ID, &attr, sizeof(attr)); | |
442 | if (!err) | |
443 | *next_id = attr.next_id; | |
444 | ||
445 | return err; | |
446 | } | |
447 | ||
448 | int bpf_prog_get_fd_by_id(__u32 id) | |
449 | { | |
450 | union bpf_attr attr; | |
451 | ||
452 | bzero(&attr, sizeof(attr)); | |
453 | attr.prog_id = id; | |
454 | ||
455 | return sys_bpf(BPF_PROG_GET_FD_BY_ID, &attr, sizeof(attr)); | |
456 | } | |
457 | ||
458 | int bpf_map_get_fd_by_id(__u32 id) | |
459 | { | |
460 | union bpf_attr attr; | |
461 | ||
462 | bzero(&attr, sizeof(attr)); | |
463 | attr.map_id = id; | |
464 | ||
465 | return sys_bpf(BPF_MAP_GET_FD_BY_ID, &attr, sizeof(attr)); | |
466 | } | |
467 | ||
cd8b8928 MKL |
468 | int bpf_btf_get_fd_by_id(__u32 id) |
469 | { | |
470 | union bpf_attr attr; | |
471 | ||
472 | bzero(&attr, sizeof(attr)); | |
473 | attr.btf_id = id; | |
474 | ||
475 | return sys_bpf(BPF_BTF_GET_FD_BY_ID, &attr, sizeof(attr)); | |
476 | } | |
477 | ||
95b9afd3 MKL |
478 | int bpf_obj_get_info_by_fd(int prog_fd, void *info, __u32 *info_len) |
479 | { | |
480 | union bpf_attr attr; | |
481 | int err; | |
482 | ||
483 | bzero(&attr, sizeof(attr)); | |
95b9afd3 MKL |
484 | attr.info.bpf_fd = prog_fd; |
485 | attr.info.info_len = *info_len; | |
486 | attr.info.info = ptr_to_u64(info); | |
487 | ||
488 | err = sys_bpf(BPF_OBJ_GET_INFO_BY_FD, &attr, sizeof(attr)); | |
489 | if (!err) | |
490 | *info_len = attr.info.info_len; | |
491 | ||
492 | return err; | |
493 | } | |
949abbe8 | 494 | |
a0fe3e57 AS |
495 | int bpf_raw_tracepoint_open(const char *name, int prog_fd) |
496 | { | |
497 | union bpf_attr attr; | |
498 | ||
499 | bzero(&attr, sizeof(attr)); | |
500 | attr.raw_tracepoint.name = ptr_to_u64(name); | |
501 | attr.raw_tracepoint.prog_fd = prog_fd; | |
502 | ||
503 | return sys_bpf(BPF_RAW_TRACEPOINT_OPEN, &attr, sizeof(attr)); | |
504 | } | |
505 | ||
8a138aed MKL |
506 | int bpf_load_btf(void *btf, __u32 btf_size, char *log_buf, __u32 log_buf_size, |
507 | bool do_log) | |
508 | { | |
509 | union bpf_attr attr = {}; | |
510 | int fd; | |
511 | ||
512 | attr.btf = ptr_to_u64(btf); | |
513 | attr.btf_size = btf_size; | |
514 | ||
515 | retry: | |
516 | if (do_log && log_buf && log_buf_size) { | |
517 | attr.btf_log_level = 1; | |
518 | attr.btf_log_size = log_buf_size; | |
519 | attr.btf_log_buf = ptr_to_u64(log_buf); | |
520 | } | |
521 | ||
522 | fd = sys_bpf(BPF_BTF_LOAD, &attr, sizeof(attr)); | |
523 | if (fd == -1 && !do_log && log_buf && log_buf_size) { | |
524 | do_log = true; | |
525 | goto retry; | |
526 | } | |
527 | ||
528 | return fd; | |
529 | } | |
30687ad9 YS |
530 | |
531 | int bpf_task_fd_query(int pid, int fd, __u32 flags, char *buf, __u32 *buf_len, | |
532 | __u32 *prog_id, __u32 *fd_type, __u64 *probe_offset, | |
533 | __u64 *probe_addr) | |
534 | { | |
535 | union bpf_attr attr = {}; | |
536 | int err; | |
537 | ||
538 | attr.task_fd_query.pid = pid; | |
539 | attr.task_fd_query.fd = fd; | |
540 | attr.task_fd_query.flags = flags; | |
541 | attr.task_fd_query.buf = ptr_to_u64(buf); | |
542 | attr.task_fd_query.buf_len = *buf_len; | |
543 | ||
544 | err = sys_bpf(BPF_TASK_FD_QUERY, &attr, sizeof(attr)); | |
545 | *buf_len = attr.task_fd_query.buf_len; | |
546 | *prog_id = attr.task_fd_query.prog_id; | |
547 | *fd_type = attr.task_fd_query.fd_type; | |
548 | *probe_offset = attr.task_fd_query.probe_offset; | |
549 | *probe_addr = attr.task_fd_query.probe_addr; | |
550 | ||
551 | return err; | |
552 | } |