1 // SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause)
4 * common eBPF ELF operations.
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.
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!)
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.
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>
28 #include <asm/unistd.h>
30 #include <linux/bpf.h>
33 #include "libbpf_internal.h"
36 * When building perf, unistd.h is overridden. __NR_bpf is
37 * required to be defined explicitly.
40 # if defined(__i386__)
42 # elif defined(__x86_64__)
44 # elif defined(__aarch64__)
46 # elif defined(__sparc__)
48 # elif defined(__s390__)
50 # elif defined(__arc__)
53 # error __NR_bpf not defined. libbpf does not support your arch.
57 static inline __u64
ptr_to_u64(const void *ptr
)
59 return (__u64
) (unsigned long) ptr
;
62 static inline int sys_bpf(enum bpf_cmd cmd
, union bpf_attr
*attr
,
65 return syscall(__NR_bpf
, cmd
, attr
, size
);
68 static inline int sys_bpf_prog_load(union bpf_attr
*attr
, unsigned int size
)
74 fd
= sys_bpf(BPF_PROG_LOAD
, attr
, size
);
75 } while (fd
< 0 && errno
== EAGAIN
&& retries
-- > 0);
80 int bpf_create_map_xattr(const struct bpf_create_map_attr
*create_attr
)
84 memset(&attr
, '\0', sizeof(attr
));
86 attr
.map_type
= create_attr
->map_type
;
87 attr
.key_size
= create_attr
->key_size
;
88 attr
.value_size
= create_attr
->value_size
;
89 attr
.max_entries
= create_attr
->max_entries
;
90 attr
.map_flags
= create_attr
->map_flags
;
91 if (create_attr
->name
)
92 memcpy(attr
.map_name
, create_attr
->name
,
93 min(strlen(create_attr
->name
), BPF_OBJ_NAME_LEN
- 1));
94 attr
.numa_node
= create_attr
->numa_node
;
95 attr
.btf_fd
= create_attr
->btf_fd
;
96 attr
.btf_key_type_id
= create_attr
->btf_key_type_id
;
97 attr
.btf_value_type_id
= create_attr
->btf_value_type_id
;
98 attr
.map_ifindex
= create_attr
->map_ifindex
;
99 if (attr
.map_type
== BPF_MAP_TYPE_STRUCT_OPS
)
100 attr
.btf_vmlinux_value_type_id
=
101 create_attr
->btf_vmlinux_value_type_id
;
103 attr
.inner_map_fd
= create_attr
->inner_map_fd
;
105 return sys_bpf(BPF_MAP_CREATE
, &attr
, sizeof(attr
));
108 int bpf_create_map_node(enum bpf_map_type map_type
, const char *name
,
109 int key_size
, int value_size
, int max_entries
,
110 __u32 map_flags
, int node
)
112 struct bpf_create_map_attr map_attr
= {};
114 map_attr
.name
= name
;
115 map_attr
.map_type
= map_type
;
116 map_attr
.map_flags
= map_flags
;
117 map_attr
.key_size
= key_size
;
118 map_attr
.value_size
= value_size
;
119 map_attr
.max_entries
= max_entries
;
121 map_attr
.numa_node
= node
;
122 map_attr
.map_flags
|= BPF_F_NUMA_NODE
;
125 return bpf_create_map_xattr(&map_attr
);
128 int bpf_create_map(enum bpf_map_type map_type
, int key_size
,
129 int value_size
, int max_entries
, __u32 map_flags
)
131 struct bpf_create_map_attr map_attr
= {};
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
;
139 return bpf_create_map_xattr(&map_attr
);
142 int bpf_create_map_name(enum bpf_map_type map_type
, const char *name
,
143 int key_size
, int value_size
, int max_entries
,
146 struct bpf_create_map_attr map_attr
= {};
148 map_attr
.name
= name
;
149 map_attr
.map_type
= map_type
;
150 map_attr
.map_flags
= map_flags
;
151 map_attr
.key_size
= key_size
;
152 map_attr
.value_size
= value_size
;
153 map_attr
.max_entries
= max_entries
;
155 return bpf_create_map_xattr(&map_attr
);
158 int bpf_create_map_in_map_node(enum bpf_map_type map_type
, const char *name
,
159 int key_size
, int inner_map_fd
, int max_entries
,
160 __u32 map_flags
, int node
)
164 memset(&attr
, '\0', sizeof(attr
));
166 attr
.map_type
= map_type
;
167 attr
.key_size
= key_size
;
169 attr
.inner_map_fd
= inner_map_fd
;
170 attr
.max_entries
= max_entries
;
171 attr
.map_flags
= map_flags
;
173 memcpy(attr
.map_name
, name
,
174 min(strlen(name
), BPF_OBJ_NAME_LEN
- 1));
177 attr
.map_flags
|= BPF_F_NUMA_NODE
;
178 attr
.numa_node
= node
;
181 return sys_bpf(BPF_MAP_CREATE
, &attr
, sizeof(attr
));
184 int bpf_create_map_in_map(enum bpf_map_type map_type
, const char *name
,
185 int key_size
, int inner_map_fd
, int max_entries
,
188 return bpf_create_map_in_map_node(map_type
, name
, key_size
,
189 inner_map_fd
, max_entries
, map_flags
,
194 alloc_zero_tailing_info(const void *orecord
, __u32 cnt
,
195 __u32 actual_rec_size
, __u32 expected_rec_size
)
197 __u64 info_len
= (__u64
)actual_rec_size
* cnt
;
198 void *info
, *nrecord
;
201 info
= malloc(info_len
);
205 /* zero out bytes kernel does not understand */
207 for (i
= 0; i
< cnt
; i
++) {
208 memcpy(nrecord
, orecord
, expected_rec_size
);
209 memset(nrecord
+ expected_rec_size
, 0,
210 actual_rec_size
- expected_rec_size
);
211 orecord
+= actual_rec_size
;
212 nrecord
+= actual_rec_size
;
218 int libbpf__bpf_prog_load(const struct bpf_prog_load_params
*load_attr
)
220 void *finfo
= NULL
, *linfo
= NULL
;
224 if (!load_attr
->log_buf
!= !load_attr
->log_buf_sz
)
227 if (load_attr
->log_level
> (4 | 2 | 1) || (load_attr
->log_level
&& !load_attr
->log_buf
))
230 memset(&attr
, 0, sizeof(attr
));
231 attr
.prog_type
= load_attr
->prog_type
;
232 attr
.expected_attach_type
= load_attr
->expected_attach_type
;
234 if (load_attr
->attach_prog_fd
)
235 attr
.attach_prog_fd
= load_attr
->attach_prog_fd
;
237 attr
.attach_btf_obj_fd
= load_attr
->attach_btf_obj_fd
;
238 attr
.attach_btf_id
= load_attr
->attach_btf_id
;
240 attr
.prog_ifindex
= load_attr
->prog_ifindex
;
241 attr
.kern_version
= load_attr
->kern_version
;
243 attr
.insn_cnt
= (__u32
)load_attr
->insn_cnt
;
244 attr
.insns
= ptr_to_u64(load_attr
->insns
);
245 attr
.license
= ptr_to_u64(load_attr
->license
);
247 attr
.log_level
= load_attr
->log_level
;
248 if (attr
.log_level
) {
249 attr
.log_buf
= ptr_to_u64(load_attr
->log_buf
);
250 attr
.log_size
= load_attr
->log_buf_sz
;
253 attr
.prog_btf_fd
= load_attr
->prog_btf_fd
;
254 attr
.prog_flags
= load_attr
->prog_flags
;
256 attr
.func_info_rec_size
= load_attr
->func_info_rec_size
;
257 attr
.func_info_cnt
= load_attr
->func_info_cnt
;
258 attr
.func_info
= ptr_to_u64(load_attr
->func_info
);
260 attr
.line_info_rec_size
= load_attr
->line_info_rec_size
;
261 attr
.line_info_cnt
= load_attr
->line_info_cnt
;
262 attr
.line_info
= ptr_to_u64(load_attr
->line_info
);
265 memcpy(attr
.prog_name
, load_attr
->name
,
266 min(strlen(load_attr
->name
), (size_t)BPF_OBJ_NAME_LEN
- 1));
268 fd
= sys_bpf_prog_load(&attr
, sizeof(attr
));
272 /* After bpf_prog_load, the kernel may modify certain attributes
273 * to give user space a hint how to deal with loading failure.
274 * Check to see whether we can make some changes and load again.
276 while (errno
== E2BIG
&& (!finfo
|| !linfo
)) {
277 if (!finfo
&& attr
.func_info_cnt
&&
278 attr
.func_info_rec_size
< load_attr
->func_info_rec_size
) {
279 /* try with corrected func info records */
280 finfo
= alloc_zero_tailing_info(load_attr
->func_info
,
281 load_attr
->func_info_cnt
,
282 load_attr
->func_info_rec_size
,
283 attr
.func_info_rec_size
);
287 attr
.func_info
= ptr_to_u64(finfo
);
288 attr
.func_info_rec_size
= load_attr
->func_info_rec_size
;
289 } else if (!linfo
&& attr
.line_info_cnt
&&
290 attr
.line_info_rec_size
<
291 load_attr
->line_info_rec_size
) {
292 linfo
= alloc_zero_tailing_info(load_attr
->line_info
,
293 load_attr
->line_info_cnt
,
294 load_attr
->line_info_rec_size
,
295 attr
.line_info_rec_size
);
299 attr
.line_info
= ptr_to_u64(linfo
);
300 attr
.line_info_rec_size
= load_attr
->line_info_rec_size
;
305 fd
= sys_bpf_prog_load(&attr
, sizeof(attr
));
310 if (load_attr
->log_level
|| !load_attr
->log_buf
)
313 /* Try again with log */
314 attr
.log_buf
= ptr_to_u64(load_attr
->log_buf
);
315 attr
.log_size
= load_attr
->log_buf_sz
;
317 load_attr
->log_buf
[0] = 0;
319 fd
= sys_bpf_prog_load(&attr
, sizeof(attr
));
326 int bpf_load_program_xattr(const struct bpf_load_program_attr
*load_attr
,
327 char *log_buf
, size_t log_buf_sz
)
329 struct bpf_prog_load_params p
= {};
331 if (!load_attr
|| !log_buf
!= !log_buf_sz
)
334 p
.prog_type
= load_attr
->prog_type
;
335 p
.expected_attach_type
= load_attr
->expected_attach_type
;
336 switch (p
.prog_type
) {
337 case BPF_PROG_TYPE_STRUCT_OPS
:
338 case BPF_PROG_TYPE_LSM
:
339 p
.attach_btf_id
= load_attr
->attach_btf_id
;
341 case BPF_PROG_TYPE_TRACING
:
342 case BPF_PROG_TYPE_EXT
:
343 p
.attach_btf_id
= load_attr
->attach_btf_id
;
344 p
.attach_prog_fd
= load_attr
->attach_prog_fd
;
347 p
.prog_ifindex
= load_attr
->prog_ifindex
;
348 p
.kern_version
= load_attr
->kern_version
;
350 p
.insn_cnt
= load_attr
->insns_cnt
;
351 p
.insns
= load_attr
->insns
;
352 p
.license
= load_attr
->license
;
353 p
.log_level
= load_attr
->log_level
;
355 p
.log_buf_sz
= log_buf_sz
;
356 p
.prog_btf_fd
= load_attr
->prog_btf_fd
;
357 p
.func_info_rec_size
= load_attr
->func_info_rec_size
;
358 p
.func_info_cnt
= load_attr
->func_info_cnt
;
359 p
.func_info
= load_attr
->func_info
;
360 p
.line_info_rec_size
= load_attr
->line_info_rec_size
;
361 p
.line_info_cnt
= load_attr
->line_info_cnt
;
362 p
.line_info
= load_attr
->line_info
;
363 p
.name
= load_attr
->name
;
364 p
.prog_flags
= load_attr
->prog_flags
;
366 return libbpf__bpf_prog_load(&p
);
369 int bpf_load_program(enum bpf_prog_type type
, const struct bpf_insn
*insns
,
370 size_t insns_cnt
, const char *license
,
371 __u32 kern_version
, char *log_buf
,
374 struct bpf_load_program_attr load_attr
;
376 memset(&load_attr
, 0, sizeof(struct bpf_load_program_attr
));
377 load_attr
.prog_type
= type
;
378 load_attr
.expected_attach_type
= 0;
379 load_attr
.name
= NULL
;
380 load_attr
.insns
= insns
;
381 load_attr
.insns_cnt
= insns_cnt
;
382 load_attr
.license
= license
;
383 load_attr
.kern_version
= kern_version
;
385 return bpf_load_program_xattr(&load_attr
, log_buf
, log_buf_sz
);
388 int bpf_verify_program(enum bpf_prog_type type
, const struct bpf_insn
*insns
,
389 size_t insns_cnt
, __u32 prog_flags
, const char *license
,
390 __u32 kern_version
, char *log_buf
, size_t log_buf_sz
,
395 memset(&attr
, 0, sizeof(attr
));
396 attr
.prog_type
= type
;
397 attr
.insn_cnt
= (__u32
)insns_cnt
;
398 attr
.insns
= ptr_to_u64(insns
);
399 attr
.license
= ptr_to_u64(license
);
400 attr
.log_buf
= ptr_to_u64(log_buf
);
401 attr
.log_size
= log_buf_sz
;
402 attr
.log_level
= log_level
;
404 attr
.kern_version
= kern_version
;
405 attr
.prog_flags
= prog_flags
;
407 return sys_bpf_prog_load(&attr
, sizeof(attr
));
410 int bpf_map_update_elem(int fd
, const void *key
, const void *value
,
415 memset(&attr
, 0, sizeof(attr
));
417 attr
.key
= ptr_to_u64(key
);
418 attr
.value
= ptr_to_u64(value
);
421 return sys_bpf(BPF_MAP_UPDATE_ELEM
, &attr
, sizeof(attr
));
424 int bpf_map_lookup_elem(int fd
, const void *key
, void *value
)
428 memset(&attr
, 0, sizeof(attr
));
430 attr
.key
= ptr_to_u64(key
);
431 attr
.value
= ptr_to_u64(value
);
433 return sys_bpf(BPF_MAP_LOOKUP_ELEM
, &attr
, sizeof(attr
));
436 int bpf_map_lookup_elem_flags(int fd
, const void *key
, void *value
, __u64 flags
)
440 memset(&attr
, 0, sizeof(attr
));
442 attr
.key
= ptr_to_u64(key
);
443 attr
.value
= ptr_to_u64(value
);
446 return sys_bpf(BPF_MAP_LOOKUP_ELEM
, &attr
, sizeof(attr
));
449 int bpf_map_lookup_and_delete_elem(int fd
, const void *key
, void *value
)
453 memset(&attr
, 0, sizeof(attr
));
455 attr
.key
= ptr_to_u64(key
);
456 attr
.value
= ptr_to_u64(value
);
458 return sys_bpf(BPF_MAP_LOOKUP_AND_DELETE_ELEM
, &attr
, sizeof(attr
));
461 int bpf_map_delete_elem(int fd
, const void *key
)
465 memset(&attr
, 0, sizeof(attr
));
467 attr
.key
= ptr_to_u64(key
);
469 return sys_bpf(BPF_MAP_DELETE_ELEM
, &attr
, sizeof(attr
));
472 int bpf_map_get_next_key(int fd
, const void *key
, void *next_key
)
476 memset(&attr
, 0, sizeof(attr
));
478 attr
.key
= ptr_to_u64(key
);
479 attr
.next_key
= ptr_to_u64(next_key
);
481 return sys_bpf(BPF_MAP_GET_NEXT_KEY
, &attr
, sizeof(attr
));
484 int bpf_map_freeze(int fd
)
488 memset(&attr
, 0, sizeof(attr
));
491 return sys_bpf(BPF_MAP_FREEZE
, &attr
, sizeof(attr
));
494 static int bpf_map_batch_common(int cmd
, int fd
, void *in_batch
,
495 void *out_batch
, void *keys
, void *values
,
497 const struct bpf_map_batch_opts
*opts
)
502 if (!OPTS_VALID(opts
, bpf_map_batch_opts
))
505 memset(&attr
, 0, sizeof(attr
));
506 attr
.batch
.map_fd
= fd
;
507 attr
.batch
.in_batch
= ptr_to_u64(in_batch
);
508 attr
.batch
.out_batch
= ptr_to_u64(out_batch
);
509 attr
.batch
.keys
= ptr_to_u64(keys
);
510 attr
.batch
.values
= ptr_to_u64(values
);
511 attr
.batch
.count
= *count
;
512 attr
.batch
.elem_flags
= OPTS_GET(opts
, elem_flags
, 0);
513 attr
.batch
.flags
= OPTS_GET(opts
, flags
, 0);
515 ret
= sys_bpf(cmd
, &attr
, sizeof(attr
));
516 *count
= attr
.batch
.count
;
521 int bpf_map_delete_batch(int fd
, void *keys
, __u32
*count
,
522 const struct bpf_map_batch_opts
*opts
)
524 return bpf_map_batch_common(BPF_MAP_DELETE_BATCH
, fd
, NULL
,
525 NULL
, keys
, NULL
, count
, opts
);
528 int bpf_map_lookup_batch(int fd
, void *in_batch
, void *out_batch
, void *keys
,
529 void *values
, __u32
*count
,
530 const struct bpf_map_batch_opts
*opts
)
532 return bpf_map_batch_common(BPF_MAP_LOOKUP_BATCH
, fd
, in_batch
,
533 out_batch
, keys
, values
, count
, opts
);
536 int bpf_map_lookup_and_delete_batch(int fd
, void *in_batch
, void *out_batch
,
537 void *keys
, void *values
, __u32
*count
,
538 const struct bpf_map_batch_opts
*opts
)
540 return bpf_map_batch_common(BPF_MAP_LOOKUP_AND_DELETE_BATCH
,
541 fd
, in_batch
, out_batch
, keys
, values
,
545 int bpf_map_update_batch(int fd
, void *keys
, void *values
, __u32
*count
,
546 const struct bpf_map_batch_opts
*opts
)
548 return bpf_map_batch_common(BPF_MAP_UPDATE_BATCH
, fd
, NULL
, NULL
,
549 keys
, values
, count
, opts
);
552 int bpf_obj_pin(int fd
, const char *pathname
)
556 memset(&attr
, 0, sizeof(attr
));
557 attr
.pathname
= ptr_to_u64((void *)pathname
);
560 return sys_bpf(BPF_OBJ_PIN
, &attr
, sizeof(attr
));
563 int bpf_obj_get(const char *pathname
)
567 memset(&attr
, 0, sizeof(attr
));
568 attr
.pathname
= ptr_to_u64((void *)pathname
);
570 return sys_bpf(BPF_OBJ_GET
, &attr
, sizeof(attr
));
573 int bpf_prog_attach(int prog_fd
, int target_fd
, enum bpf_attach_type type
,
576 DECLARE_LIBBPF_OPTS(bpf_prog_attach_opts
, opts
,
580 return bpf_prog_attach_xattr(prog_fd
, target_fd
, type
, &opts
);
583 int bpf_prog_attach_xattr(int prog_fd
, int target_fd
,
584 enum bpf_attach_type type
,
585 const struct bpf_prog_attach_opts
*opts
)
589 if (!OPTS_VALID(opts
, bpf_prog_attach_opts
))
592 memset(&attr
, 0, sizeof(attr
));
593 attr
.target_fd
= target_fd
;
594 attr
.attach_bpf_fd
= prog_fd
;
595 attr
.attach_type
= type
;
596 attr
.attach_flags
= OPTS_GET(opts
, flags
, 0);
597 attr
.replace_bpf_fd
= OPTS_GET(opts
, replace_prog_fd
, 0);
599 return sys_bpf(BPF_PROG_ATTACH
, &attr
, sizeof(attr
));
602 int bpf_prog_detach(int target_fd
, enum bpf_attach_type type
)
606 memset(&attr
, 0, sizeof(attr
));
607 attr
.target_fd
= target_fd
;
608 attr
.attach_type
= type
;
610 return sys_bpf(BPF_PROG_DETACH
, &attr
, sizeof(attr
));
613 int bpf_prog_detach2(int prog_fd
, int target_fd
, enum bpf_attach_type type
)
617 memset(&attr
, 0, sizeof(attr
));
618 attr
.target_fd
= target_fd
;
619 attr
.attach_bpf_fd
= prog_fd
;
620 attr
.attach_type
= type
;
622 return sys_bpf(BPF_PROG_DETACH
, &attr
, sizeof(attr
));
625 int bpf_link_create(int prog_fd
, int target_fd
,
626 enum bpf_attach_type attach_type
,
627 const struct bpf_link_create_opts
*opts
)
629 __u32 target_btf_id
, iter_info_len
;
632 if (!OPTS_VALID(opts
, bpf_link_create_opts
))
635 iter_info_len
= OPTS_GET(opts
, iter_info_len
, 0);
636 target_btf_id
= OPTS_GET(opts
, target_btf_id
, 0);
638 if (iter_info_len
&& target_btf_id
)
641 memset(&attr
, 0, sizeof(attr
));
642 attr
.link_create
.prog_fd
= prog_fd
;
643 attr
.link_create
.target_fd
= target_fd
;
644 attr
.link_create
.attach_type
= attach_type
;
645 attr
.link_create
.flags
= OPTS_GET(opts
, flags
, 0);
648 attr
.link_create
.iter_info
=
649 ptr_to_u64(OPTS_GET(opts
, iter_info
, (void *)0));
650 attr
.link_create
.iter_info_len
= iter_info_len
;
651 } else if (target_btf_id
) {
652 attr
.link_create
.target_btf_id
= target_btf_id
;
655 return sys_bpf(BPF_LINK_CREATE
, &attr
, sizeof(attr
));
658 int bpf_link_detach(int link_fd
)
662 memset(&attr
, 0, sizeof(attr
));
663 attr
.link_detach
.link_fd
= link_fd
;
665 return sys_bpf(BPF_LINK_DETACH
, &attr
, sizeof(attr
));
668 int bpf_link_update(int link_fd
, int new_prog_fd
,
669 const struct bpf_link_update_opts
*opts
)
673 if (!OPTS_VALID(opts
, bpf_link_update_opts
))
676 memset(&attr
, 0, sizeof(attr
));
677 attr
.link_update
.link_fd
= link_fd
;
678 attr
.link_update
.new_prog_fd
= new_prog_fd
;
679 attr
.link_update
.flags
= OPTS_GET(opts
, flags
, 0);
680 attr
.link_update
.old_prog_fd
= OPTS_GET(opts
, old_prog_fd
, 0);
682 return sys_bpf(BPF_LINK_UPDATE
, &attr
, sizeof(attr
));
685 int bpf_iter_create(int link_fd
)
689 memset(&attr
, 0, sizeof(attr
));
690 attr
.iter_create
.link_fd
= link_fd
;
692 return sys_bpf(BPF_ITER_CREATE
, &attr
, sizeof(attr
));
695 int bpf_prog_query(int target_fd
, enum bpf_attach_type type
, __u32 query_flags
,
696 __u32
*attach_flags
, __u32
*prog_ids
, __u32
*prog_cnt
)
701 memset(&attr
, 0, sizeof(attr
));
702 attr
.query
.target_fd
= target_fd
;
703 attr
.query
.attach_type
= type
;
704 attr
.query
.query_flags
= query_flags
;
705 attr
.query
.prog_cnt
= *prog_cnt
;
706 attr
.query
.prog_ids
= ptr_to_u64(prog_ids
);
708 ret
= sys_bpf(BPF_PROG_QUERY
, &attr
, sizeof(attr
));
710 *attach_flags
= attr
.query
.attach_flags
;
711 *prog_cnt
= attr
.query
.prog_cnt
;
715 int bpf_prog_test_run(int prog_fd
, int repeat
, void *data
, __u32 size
,
716 void *data_out
, __u32
*size_out
, __u32
*retval
,
722 memset(&attr
, 0, sizeof(attr
));
723 attr
.test
.prog_fd
= prog_fd
;
724 attr
.test
.data_in
= ptr_to_u64(data
);
725 attr
.test
.data_out
= ptr_to_u64(data_out
);
726 attr
.test
.data_size_in
= size
;
727 attr
.test
.repeat
= repeat
;
729 ret
= sys_bpf(BPF_PROG_TEST_RUN
, &attr
, sizeof(attr
));
731 *size_out
= attr
.test
.data_size_out
;
733 *retval
= attr
.test
.retval
;
735 *duration
= attr
.test
.duration
;
739 int bpf_prog_test_run_xattr(struct bpf_prog_test_run_attr
*test_attr
)
744 if (!test_attr
->data_out
&& test_attr
->data_size_out
> 0)
747 memset(&attr
, 0, sizeof(attr
));
748 attr
.test
.prog_fd
= test_attr
->prog_fd
;
749 attr
.test
.data_in
= ptr_to_u64(test_attr
->data_in
);
750 attr
.test
.data_out
= ptr_to_u64(test_attr
->data_out
);
751 attr
.test
.data_size_in
= test_attr
->data_size_in
;
752 attr
.test
.data_size_out
= test_attr
->data_size_out
;
753 attr
.test
.ctx_in
= ptr_to_u64(test_attr
->ctx_in
);
754 attr
.test
.ctx_out
= ptr_to_u64(test_attr
->ctx_out
);
755 attr
.test
.ctx_size_in
= test_attr
->ctx_size_in
;
756 attr
.test
.ctx_size_out
= test_attr
->ctx_size_out
;
757 attr
.test
.repeat
= test_attr
->repeat
;
759 ret
= sys_bpf(BPF_PROG_TEST_RUN
, &attr
, sizeof(attr
));
760 test_attr
->data_size_out
= attr
.test
.data_size_out
;
761 test_attr
->ctx_size_out
= attr
.test
.ctx_size_out
;
762 test_attr
->retval
= attr
.test
.retval
;
763 test_attr
->duration
= attr
.test
.duration
;
767 int bpf_prog_test_run_opts(int prog_fd
, struct bpf_test_run_opts
*opts
)
772 if (!OPTS_VALID(opts
, bpf_test_run_opts
))
775 memset(&attr
, 0, sizeof(attr
));
776 attr
.test
.prog_fd
= prog_fd
;
777 attr
.test
.cpu
= OPTS_GET(opts
, cpu
, 0);
778 attr
.test
.flags
= OPTS_GET(opts
, flags
, 0);
779 attr
.test
.repeat
= OPTS_GET(opts
, repeat
, 0);
780 attr
.test
.duration
= OPTS_GET(opts
, duration
, 0);
781 attr
.test
.ctx_size_in
= OPTS_GET(opts
, ctx_size_in
, 0);
782 attr
.test
.ctx_size_out
= OPTS_GET(opts
, ctx_size_out
, 0);
783 attr
.test
.data_size_in
= OPTS_GET(opts
, data_size_in
, 0);
784 attr
.test
.data_size_out
= OPTS_GET(opts
, data_size_out
, 0);
785 attr
.test
.ctx_in
= ptr_to_u64(OPTS_GET(opts
, ctx_in
, NULL
));
786 attr
.test
.ctx_out
= ptr_to_u64(OPTS_GET(opts
, ctx_out
, NULL
));
787 attr
.test
.data_in
= ptr_to_u64(OPTS_GET(opts
, data_in
, NULL
));
788 attr
.test
.data_out
= ptr_to_u64(OPTS_GET(opts
, data_out
, NULL
));
790 ret
= sys_bpf(BPF_PROG_TEST_RUN
, &attr
, sizeof(attr
));
791 OPTS_SET(opts
, data_size_out
, attr
.test
.data_size_out
);
792 OPTS_SET(opts
, ctx_size_out
, attr
.test
.ctx_size_out
);
793 OPTS_SET(opts
, duration
, attr
.test
.duration
);
794 OPTS_SET(opts
, retval
, attr
.test
.retval
);
798 static int bpf_obj_get_next_id(__u32 start_id
, __u32
*next_id
, int cmd
)
803 memset(&attr
, 0, sizeof(attr
));
804 attr
.start_id
= start_id
;
806 err
= sys_bpf(cmd
, &attr
, sizeof(attr
));
808 *next_id
= attr
.next_id
;
813 int bpf_prog_get_next_id(__u32 start_id
, __u32
*next_id
)
815 return bpf_obj_get_next_id(start_id
, next_id
, BPF_PROG_GET_NEXT_ID
);
818 int bpf_map_get_next_id(__u32 start_id
, __u32
*next_id
)
820 return bpf_obj_get_next_id(start_id
, next_id
, BPF_MAP_GET_NEXT_ID
);
823 int bpf_btf_get_next_id(__u32 start_id
, __u32
*next_id
)
825 return bpf_obj_get_next_id(start_id
, next_id
, BPF_BTF_GET_NEXT_ID
);
828 int bpf_link_get_next_id(__u32 start_id
, __u32
*next_id
)
830 return bpf_obj_get_next_id(start_id
, next_id
, BPF_LINK_GET_NEXT_ID
);
833 int bpf_prog_get_fd_by_id(__u32 id
)
837 memset(&attr
, 0, sizeof(attr
));
840 return sys_bpf(BPF_PROG_GET_FD_BY_ID
, &attr
, sizeof(attr
));
843 int bpf_map_get_fd_by_id(__u32 id
)
847 memset(&attr
, 0, sizeof(attr
));
850 return sys_bpf(BPF_MAP_GET_FD_BY_ID
, &attr
, sizeof(attr
));
853 int bpf_btf_get_fd_by_id(__u32 id
)
857 memset(&attr
, 0, sizeof(attr
));
860 return sys_bpf(BPF_BTF_GET_FD_BY_ID
, &attr
, sizeof(attr
));
863 int bpf_link_get_fd_by_id(__u32 id
)
867 memset(&attr
, 0, sizeof(attr
));
870 return sys_bpf(BPF_LINK_GET_FD_BY_ID
, &attr
, sizeof(attr
));
873 int bpf_obj_get_info_by_fd(int bpf_fd
, void *info
, __u32
*info_len
)
878 memset(&attr
, 0, sizeof(attr
));
879 attr
.info
.bpf_fd
= bpf_fd
;
880 attr
.info
.info_len
= *info_len
;
881 attr
.info
.info
= ptr_to_u64(info
);
883 err
= sys_bpf(BPF_OBJ_GET_INFO_BY_FD
, &attr
, sizeof(attr
));
885 *info_len
= attr
.info
.info_len
;
890 int bpf_raw_tracepoint_open(const char *name
, int prog_fd
)
894 memset(&attr
, 0, sizeof(attr
));
895 attr
.raw_tracepoint
.name
= ptr_to_u64(name
);
896 attr
.raw_tracepoint
.prog_fd
= prog_fd
;
898 return sys_bpf(BPF_RAW_TRACEPOINT_OPEN
, &attr
, sizeof(attr
));
901 int bpf_load_btf(const void *btf
, __u32 btf_size
, char *log_buf
, __u32 log_buf_size
,
904 union bpf_attr attr
= {};
907 attr
.btf
= ptr_to_u64(btf
);
908 attr
.btf_size
= btf_size
;
911 if (do_log
&& log_buf
&& log_buf_size
) {
912 attr
.btf_log_level
= 1;
913 attr
.btf_log_size
= log_buf_size
;
914 attr
.btf_log_buf
= ptr_to_u64(log_buf
);
917 fd
= sys_bpf(BPF_BTF_LOAD
, &attr
, sizeof(attr
));
918 if (fd
== -1 && !do_log
&& log_buf
&& log_buf_size
) {
926 int bpf_task_fd_query(int pid
, int fd
, __u32 flags
, char *buf
, __u32
*buf_len
,
927 __u32
*prog_id
, __u32
*fd_type
, __u64
*probe_offset
,
930 union bpf_attr attr
= {};
933 attr
.task_fd_query
.pid
= pid
;
934 attr
.task_fd_query
.fd
= fd
;
935 attr
.task_fd_query
.flags
= flags
;
936 attr
.task_fd_query
.buf
= ptr_to_u64(buf
);
937 attr
.task_fd_query
.buf_len
= *buf_len
;
939 err
= sys_bpf(BPF_TASK_FD_QUERY
, &attr
, sizeof(attr
));
940 *buf_len
= attr
.task_fd_query
.buf_len
;
941 *prog_id
= attr
.task_fd_query
.prog_id
;
942 *fd_type
= attr
.task_fd_query
.fd_type
;
943 *probe_offset
= attr
.task_fd_query
.probe_offset
;
944 *probe_addr
= attr
.task_fd_query
.probe_addr
;
949 int bpf_enable_stats(enum bpf_stats_type type
)
953 memset(&attr
, 0, sizeof(attr
));
954 attr
.enable_stats
.type
= type
;
956 return sys_bpf(BPF_ENABLE_STATS
, &attr
, sizeof(attr
));
959 int bpf_prog_bind_map(int prog_fd
, int map_fd
,
960 const struct bpf_prog_bind_opts
*opts
)
964 if (!OPTS_VALID(opts
, bpf_prog_bind_opts
))
967 memset(&attr
, 0, sizeof(attr
));
968 attr
.prog_bind_map
.prog_fd
= prog_fd
;
969 attr
.prog_bind_map
.map_fd
= map_fd
;
970 attr
.prog_bind_map
.flags
= OPTS_GET(opts
, flags
, 0);
972 return sys_bpf(BPF_PROG_BIND_MAP
, &attr
, sizeof(attr
));