]> Git Repo - linux.git/blob - tools/lib/bpf/bpf.c
Merge tag 'pwm/for-4.20-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/thierry...
[linux.git] / tools / lib / bpf / bpf.c
1 // SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause)
2
3 /*
4  * common eBPF ELF operations.
5  *
6  * Copyright (C) 2013-2015 Alexei Starovoitov <[email protected]>
7  * Copyright (C) 2015 Wang Nan <[email protected]>
8  * Copyright (C) 2015 Huawei Inc.
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>
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"
30 #include "libbpf.h"
31 #include <errno.h>
32
33 /*
34  * When building perf, unistd.h is overridden. __NR_bpf is
35  * required to be defined explicitly.
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
44 # elif defined(__sparc__)
45 #  define __NR_bpf 349
46 # elif defined(__s390__)
47 #  define __NR_bpf 351
48 # else
49 #  error __NR_bpf not defined. libbpf does not support your arch.
50 # endif
51 #endif
52
53 #ifndef min
54 #define min(x, y) ((x) < (y) ? (x) : (y))
55 #endif
56
57 static inline __u64 ptr_to_u64(const void *ptr)
58 {
59         return (__u64) (unsigned long) ptr;
60 }
61
62 static inline int sys_bpf(enum bpf_cmd cmd, union bpf_attr *attr,
63                           unsigned int size)
64 {
65         return syscall(__NR_bpf, cmd, attr, size);
66 }
67
68 int bpf_create_map_xattr(const struct bpf_create_map_attr *create_attr)
69 {
70         __u32 name_len = create_attr->name ? strlen(create_attr->name) : 0;
71         union bpf_attr attr;
72
73         memset(&attr, '\0', sizeof(attr));
74
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;
84         attr.btf_key_type_id = create_attr->btf_key_type_id;
85         attr.btf_value_type_id = create_attr->btf_value_type_id;
86         attr.map_ifindex = create_attr->map_ifindex;
87         attr.inner_map_fd = create_attr->inner_map_fd;
88
89         return sys_bpf(BPF_MAP_CREATE, &attr, sizeof(attr));
90 }
91
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;
104         if (node >= 0) {
105                 map_attr.numa_node = node;
106                 map_attr.map_flags |= BPF_F_NUMA_NODE;
107         }
108
109         return bpf_create_map_xattr(&map_attr);
110 }
111
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 {
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);
124 }
125
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 {
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);
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,
144                                __u32 map_flags, int node)
145 {
146         __u32 name_len = name ? strlen(name) : 0;
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;
157         memcpy(attr.map_name, name, min(name_len, BPF_OBJ_NAME_LEN - 1));
158
159         if (node >= 0) {
160                 attr.map_flags |= BPF_F_NUMA_NODE;
161                 attr.numa_node = node;
162         }
163
164         return sys_bpf(BPF_MAP_CREATE, &attr, sizeof(attr));
165 }
166
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)
170 {
171         return bpf_create_map_in_map_node(map_type, name, key_size,
172                                           inner_map_fd, max_entries, map_flags,
173                                           -1);
174 }
175
176 int bpf_load_program_xattr(const struct bpf_load_program_attr *load_attr,
177                            char *log_buf, size_t log_buf_sz)
178 {
179         union bpf_attr attr;
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;
187
188         bzero(&attr, sizeof(attr));
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);
194         attr.log_buf = ptr_to_u64(NULL);
195         attr.log_size = 0;
196         attr.log_level = 0;
197         attr.kern_version = load_attr->kern_version;
198         attr.prog_ifindex = load_attr->prog_ifindex;
199         memcpy(attr.prog_name, load_attr->name,
200                min(name_len, BPF_OBJ_NAME_LEN - 1));
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 }
213
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 {
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);
231 }
232
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,
236                        char *log_buf, size_t log_buf_sz, int log_level)
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;
247         attr.log_level = log_level;
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
255 int bpf_map_update_elem(int fd, const void *key, const void *value,
256                         __u64 flags)
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 }
268
269 int bpf_map_lookup_elem(int fd, const void *key, void *value)
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
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
293 int bpf_map_delete_elem(int fd, const void *key)
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
304 int bpf_map_get_next_key(int fd, const void *key, void *next_key)
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 }
336
337 int bpf_prog_attach(int prog_fd, int target_fd, enum bpf_attach_type type,
338                     unsigned int flags)
339 {
340         union bpf_attr attr;
341
342         bzero(&attr, sizeof(attr));
343         attr.target_fd     = target_fd;
344         attr.attach_bpf_fd = prog_fd;
345         attr.attach_type   = type;
346         attr.attach_flags  = flags;
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 }
361
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
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
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 }
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
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
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));
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 }
494
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
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 }
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 }
This page took 0.064681 seconds and 4 git commands to generate.