Giter Club home page Giter Club logo

libbpf's Introduction

libbpf Github Actions Builds & Tests Coverity CodeQL OSS-Fuzz Status Read the Docs

This is the official home of the libbpf library.

Please use this Github repository for building and packaging libbpf and when using it in your projects through Git submodule.

Libbpf authoritative source code is developed as part of bpf-next Linux source tree under tools/lib/bpf subdirectory and is periodically synced to Github. As such, all the libbpf changes should be sent to BPF mailing list, please don't open PRs here unless you are changing Github-specific parts of libbpf (e.g., Github-specific Makefile).

Libbpf and general BPF usage questions

Libbpf documentation can be found here. It's an ongoing effort and has ways to go, but please take a look and consider contributing as well.

Please check out libbpf-bootstrap and the companion blog post for the examples of building BPF applications with libbpf. libbpf-tools are also a good source of the real-world libbpf-based tracing tools.

See also "BPF CO-RE reference guide" for the coverage of practical aspects of building BPF CO-RE applications and "BPF CO-RE" for general introduction into BPF portability issues and BPF CO-RE origins.

All general BPF questions, including kernel functionality, libbpf APIs and their application, should be sent to [email protected] mailing list. You can subscribe to it here and search its archive here. Please search the archive before asking new questions. It very well might be that this was already addressed or answered before.

[email protected] is monitored by many more people and they will happily try to help you with whatever issue you have. This repository's PRs and issues should be opened only for dealing with issues pertaining to specific way this libbpf mirror repo is set up and organized.

Building libbpf

libelf is an internal dependency of libbpf and thus it is required to link against and must be installed on the system for applications to work. pkg-config is used by default to find libelf, and the program called can be overridden with PKG_CONFIG.

If using pkg-config at build time is not desired, it can be disabled by setting NO_PKG_CONFIG=1 when calling make.

To build both static libbpf.a and shared libbpf.so:

$ cd src
$ make

To build only static libbpf.a library in directory build/ and install them together with libbpf headers in a staging directory root/:

$ cd src
$ mkdir build root
$ BUILD_STATIC_ONLY=y OBJDIR=build DESTDIR=root make install

To build both static libbpf.a and shared libbpf.so against a custom libelf dependency installed in /build/root/ and install them together with libbpf headers in a build directory /build/root/:

$ cd src
$ PKG_CONFIG_PATH=/build/root/lib64/pkgconfig DESTDIR=/build/root make install

BPF CO-RE (Compile Once – Run Everywhere)

Libbpf supports building BPF CO-RE-enabled applications, which, in contrast to BCC, do not require Clang/LLVM runtime being deployed to target servers and doesn't rely on kernel-devel headers being available.

It does rely on kernel to be built with BTF type information, though. Some major Linux distributions come with kernel BTF already built in:

  • Fedora 31+
  • RHEL 8.2+
  • OpenSUSE Tumbleweed (in the next release, as of 2020-06-04)
  • Arch Linux (from kernel 5.7.1.arch1-1)
  • Manjaro (from kernel 5.4 if compiled after 2021-06-18)
  • Ubuntu 20.10
  • Debian 11 (amd64/arm64)

If your kernel doesn't come with BTF built-in, you'll need to build custom kernel. You'll need:

  • pahole 1.16+ tool (part of dwarves package), which performs DWARF to BTF conversion;
  • kernel built with CONFIG_DEBUG_INFO_BTF=y option;
  • you can check if your kernel has BTF built-in by looking for /sys/kernel/btf/vmlinux file:
$ ls -la /sys/kernel/btf/vmlinux
-r--r--r--. 1 root root 3541561 Jun  2 18:16 /sys/kernel/btf/vmlinux

To develop and build BPF programs, you'll need Clang/LLVM 10+. The following distributions have Clang/LLVM 10+ packaged by default:

  • Fedora 32+
  • Ubuntu 20.04+
  • Arch Linux
  • Ubuntu 20.10 (LLVM 11)
  • Debian 11 (LLVM 11)
  • Alpine 3.13+

Otherwise, please make sure to update it on your system.

The following resources are useful to understand what BPF CO-RE is and how to use it:

Distributions

Distributions packaging libbpf from this mirror:

Benefits of packaging from the mirror over packaging from kernel sources:

  • Consistent versioning across distributions.
  • No ties to any specific kernel, transparent handling of older kernels. Libbpf is designed to be kernel-agnostic and work across multitude of kernel versions. It has built-in mechanisms to gracefully handle older kernels, that are missing some of the features, by working around or gracefully degrading functionality. Thus libbpf is not tied to a specific kernel version and can/should be packaged and versioned independently.
  • Continuous integration testing via GitHub Actions.
  • Static code analysis via LGTM and Coverity.

Package dependencies of libbpf, package names may vary across distros:

  • zlib
  • libelf

libbpf distro packaging status

bpf-next to Github sync

All the gory details of syncing can be found in scripts/sync-kernel.sh script. See SYNC.md for instruction.

Some header files in this repo (include/linux/*.h) are reduced versions of their counterpart files at bpf-next's tools/include/linux/*.h to make compilation successful.

License

This work is dual-licensed under BSD 2-clause license and GNU LGPL v2.1 license. You can choose between one of them if you use this work.

SPDX-License-Identifier: BSD-2-Clause OR LGPL-2.1

libbpf's People

Contributors

acmel avatar alan-maguire avatar anakryiko avatar bluca avatar borkmann avatar byte-lab avatar chantra avatar chenhengqi avatar d-e-s-o avatar davemarchevsky avatar eddyz87 avatar evverx avatar florentrevest avatar grantseltzer avatar haoluo1022 avatar iamkafai avatar iii-i avatar joannekoong avatar kkdwivedi avatar liu-song-6 avatar liuhangbin avatar lorenzobianconi avatar magnus-karlsson avatar mrc0mmand avatar olsajiri avatar qmonnet avatar rdna avatar sinkap avatar tohojo avatar yonghong-song avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

libbpf's Issues

Attach lwt_seg6local program type

Hi,

First of all please excuse me to submit a new issue for this problem. I tried to contact you at XX but all my mails got rejected by the system.

Until recently I worked with BCC to load programs into the kernel and communicate with them in the userspace. I jumped to libbpf for performance reasons, and libbpf seems to be the future of bpf.

I work with BPF_PROG_TYPE_LWT_SEG6LOCAL programs, that are attached to an IPv6 Segment Routing route with the associated End.BPF SRv6 action. After the program is loaded into the kernel via BCC, I could attach it to the right hook using pyroute2 - it requires the file descriptor of the program to attach it to the route.

However here with libbpf I cannot do the same. From the source code, I see that we cannot attach such programs:

BPF_PROG_SEC("lwt_seg6local", BPF_PROG_TYPE_LWT_SEG6LOCAL),

libbpf/src/libbpf.c

Lines 8537 to 8538 in 986962f

/* Programs that can NOT be attached. */
#define BPF_PROG_SEC(string, ptype) BPF_PROG_SEC_IMPL(string, ptype, 0, 0, 0, 0)

It seems logical, as said earlier, such programs must be attached via an IPv6 Segment Routing route.
I tried to get the file descriptor of the program with bpf_object_btf__fd or bpf_program__fd but the given fd are wrong. For example, launching two times in parallel the same program (or even two different) give the same fd for both.

Using bpftool, I can get the program id, but it seems to be insufficient to load the program into the kernel at the correct hook: giving the retrieved id to pyroute2 does not work. Trying to inject the my_prog.bpf.o object of my program with iproute2 does not work either, as the program section I provide is not correct. Here is an example of a bpf program that will be compiled using libbpf:

#include <linux/bpf.h>
#include <bpf/bpf_helpers.h>

char LICENCE[] SEC("license") = "Dual BSD/GPL";

SEC("lwt_seg6local")
int notify_ok(struct __sk_buff *skb) {
    bpf_printk("BPF triggered from packet with SRv6 !\n");
    
    return BPF_OK;
}

And the output of iproute2 is:

Program section 'notify_ok' not found in ELF file!
Error fetching program/map!
Failed to parse eBPF program: Operation not permitted

So I wonder if I am doing something wrong here, or if it would be better to stick with BCC for now, as libbpf would be more suited for tracing purposes.

Once again, please excuse me to start an issue for this, but I do not have any other way of contact here.

Thank you in advance

library code won't link?

#include <stdio.h>
#include <assert.h>
#include <linux/bpf.h>
#include "libbpf.h"
#include <unistd.h>
#include <arpa/inet.h>

int main(int ac, char **argv)
{
struct bpf_object *obj;
int map_fd, prog_fd;

if (bpf_prog_load("test.o", BPF_PROG_TYPE_SOCKET_FILTER,
          &obj, &prog_fd))
    return 1;

}

gcc -Wall -std=c11 -L. -llibbpf test-user.c -o test-user

In file included from test-user.c:5:0:
libbpf.h:125:10: warning: ‘enum bpf_attach_type’ declared inside parameter list
enum bpf_attach_type *expected_attach_type);
^
libbpf.h:125:10: warning: its scope is only this definition or declaration, which is probably not what you want
libbpf.h:127:13: warning: ‘enum bpf_attach_type’ declared inside parameter list
enum bpf_attach_type *attach_type);
^
libbpf.h:247:16: warning: ‘enum bpf_attach_type’ declared inside parameter list
enum bpf_attach_type type);
^
libbpf.h:326:23: error: field ‘expected_attach_type’ has incomplete type
enum bpf_attach_type expected_attach_type;
^
libbpf.h:444:23: error: field ‘info’ has incomplete type
struct bpf_prog_info info;

xsk_socket__create() failed with ENOTSUP when run in gcloud with kernel 5.0

Hi All:
I am using libbpf version 0.0.4 , and trying to create AFXDP single socket I was able to see the code working only when I had ubuntu 5.3 or higher but anything lower than that resulted in socket_creation failure with errno 95, I captured my testing results here :-

  • v5.0.0-1022-gke | Failed | ENOTSUP
  • v5.1.0 | Failed | ENOTSUP
  • v5.2.0 | Failed | ENOTSUP
  • v5.3.0 | Passed |  
  • v5.4.2 | Passed

when I traced the code it failed during socket bind
695 sxdp.sxdp_family = PF_XDP;
696 sxdp.sxdp_ifindex = xsk->ifindex;
697 sxdp.sxdp_queue_id = xsk->queue_id;
698 if (umem->refcount > 1) {
699 sxdp.sxdp_flags = XDP_SHARED_UMEM;
700 sxdp.sxdp_shared_umem_fd = umem->fd;
701 } else {
702 sxdp.sxdp_flags = xsk->config.bind_flags;
703 }
704
705 err = bind(xsk->fd, (struct sockaddr *)&sxdp, sizeof(sxdp));
706 if (err) {
707 err = -errno;
708 goto out_mmap_tx;
709 }

are the older kernels missing some patches , is there anyway I can get the above to work with gcloud 5.0 ?
here is the output of uname -a for reference
Linux snort-xmt46 5.0.0-1022-gke #22~18.04.3-Ubuntu SMP Thu Oct 10 19:41:43 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux

Also is there any dependancies between a specific libbpf version and the kernel we are using ? is it documented anywhere ?

Thanks,
Mohamed

Is it possible to do SHARED_UMEM between processes?

I am struggling with my project to get SHARED_UMEM running between two or more processes. I made some changes to the lib in order to be able to copy struct xsk_umem into shared memory and reuse the umem on the sub-process.

But now I get the error:

symbol lookup error: /lib/x86_64-linux-gnu/libpthread.so.0: undefined symbol: _dl_allocate_tls, version GLIBC_PRIVATE

In my opinion, a working example for SHARED_UMEM is strongly required. The only information I find about this topic is an e-mail from Nov, 2019 in the linux mailing list and two sentences from here : https://www.kernel.org/doc/html/latest/networking/af_xdp.html#xdp-shared-umem-bind-flag

Please!!

Edit: For example, do I still have to call

	ret = xsk_ring_prod__reserve(&umem->fq,
				     XSK_RING_PROD__DEFAULT_NUM_DESCS,
				     &idx);

Because if I do this I get:

Inconsistency detected by ld.so: dl-fini.c: 87: _dl_fini: Assertion ns != LM_ID_BASE || i == nloaded' failed!`

Expose BPF_PROG_LOAD log_size and log_level?

I'm not seeing an a mechanism by which to set the BPF_PROG_LOAD log_level and log_size.

So I modified the source a bit to set the log_level = 1:

diff --git a/src/bpf.c b/src/bpf.c
index c70333f..dfd9cbc 100644
--- a/src/bpf.c
+++ b/src/bpf.c
@@ -238,6 +238,8 @@ int bpf_load_program_xattr(const struct bpf_load_program_attr *load_attr,
        attr.insns = ptr_to_u64(load_attr->insns);
        attr.license = ptr_to_u64(load_attr->license);

+
+       log_level = 1;
        attr.log_level = log_level;
        if (log_level) {
                attr.log_buf = ptr_to_u64(log_buf);

This change seems to expose an off-by-one error for BPF_LOG_BUF_SIZE

For example, I am unable to load this trivial eBPF socket filter code:

#include <linux/bpf.h>
#include "bpf_helpers.h"
SEC("dummy_socket_filter")
int socket_filter(struct __sk_buff *skb)
{
   return 0;
}
char _license[] SEC("license") = "GPL";

via this application:

#include <bpf/libbpf.h>
#include <bpf/bpf.h>
#include <stdio.h>

int main(void)
{
   void* obj;
   struct bpf_object_open_attr open_attr;
   struct bpf_program* prog;

   open_attr.prog_type = BPF_PROG_TYPE_SOCKET_FILTER;
   open_attr.file = "dummy.o";

   obj = bpf_object__open_xattr(&open_attr);
   prog = bpf_object__find_program_by_title(obj, "dummy_socket_filter");

   bpf_program__set_type(prog, BPF_PROG_TYPE_SOCKET_FILTER);
   printf("load to kernel = %d\n", bpf_program__load(prog, "GPL", 0));
   return 0;
}

I get:

libbpf: load bpf program failed: Invalid argument
libbpf: failed to load program 'dummy_socket_filter'
load to kernel = -4009

It looks like this is due to a log buffer size check in the kernel. If I reduce the BPF_LOG_BUF_SIZE, things work as expected

diff --git a/src/bpf.h b/src/bpf.h
index bc30783..697f86a 100644
--- a/src/bpf.h
+++ b/src/bpf.h
@@ -92,7 +92,7 @@ struct bpf_load_program_attr {
 #define MAPS_RELAX_COMPAT      0x01

 /* Recommend log buffer size */
-#define BPF_LOG_BUF_SIZE (16 * 1024 * 1024) /* verifier maximum in kernels <= 5.1 */
+#define BPF_LOG_BUF_SIZE ((16 * 1024 * 1024) -1 ) /* verifier maximum in kernels <= 5.1 */
 LIBBPF_API int
 bpf_load_program_xattr(const struct bpf_load_program_attr *load_attr,
                       char *log_buf, size_t log_buf_sz);

bpf_prog_load() - failed to find program symbol at offset 0, No such file or directory

When attempting to load a basic xdp program, bpf_prog_load() fails with:

libbpf: sec 'xdp': failed to find program symbol at offset 0
ERROR: loading BPF-OBJ file(./xdp_pass_kern.o) (-2): No such file or directory

Environment

  • CentOS 7.9.2009
  • Kernel: kernel-ml-5.10.14-1.el7.elrepo.x86_64
  • Clang/LLVM version 5.0.1
  • GCC 8.3.1

Reproduction

git clone https://github.com/libbpf/libbpf.git
git branch
* master
cd libbpf/src/
make all OBJDIR=.; mkdir -p build; make install_headers DESTDIR=build OBJDIR=.;

mkdir ../test; cd ../test
clang -S \
  -target bpf \
  -D __BPF_TRACING__ \
  -I../src/build/usr/include \
  -Wall \
  -Wno-unused-value \
  -Wno-pointer-sign \
  -Wno-compare-distinct-pointer-types \
  -Werror \
  -O2 -emit-llvm -c -g -o xdp_pass_kern.ll xdp_pass_kern.c
llc -march=bpf -filetype=obj -o xdp_pass_kern.o xdp_pass_kern.ll
gcc -Wall -Wextra -Wunused -I../src/build/usr/include -L../src -o xdp_pass_user xdp_pass_user.c -l:libbpf.a -lelf -lz

./xdp_pass_user
libbpf: sec 'xdp': failed to find program symbol at offset 0
ERROR: loading BPF-OBJ file(./xdp_pass_kern.o) (-2): No such file or directory

xdp_pass_kern.c:

#include <linux/bpf.h>
#include <bpf/bpf_helpers.h>
SEC("xdp")
int simple_pass_prog(struct xdp_md *ctx) {
        return XDP_PASS;
}
char _license[] SEC("license") = "GPL";

xdp_pass_user.c

#include <stdio.h>
#include <errno.h>
#include <bpf/bpf.h>
#include <bpf/libbpf.h>
int main(void) {
        int prog_fd;
        struct bpf_object *obj;
        int err;
        err = bpf_prog_load("./xdp_pass_kern.o", BPF_PROG_TYPE_XDP, &obj, &prog_fd);
        if(err) {
                fprintf(stderr, "ERROR: loading BPF-OBJ file(%s) (%d): %s\n", "./xdp_pass_kern.o", err, strerror(-err));
                return -1;
        }
 return 0;
}

I'm clearly missing something somewhere?
Thanks in advance :)

libbpf: elf: skipping unrecognized data section(16) .eh_frame

I'm trying to resolve niclashedam/ebpf-kill-example#2. When I compile my simple eBPF and load it with libbpf, I receive two warnings from libelf.

libbpf: elf: skipping unrecognized data section(16) .eh_frame
libbpf: elf: skipping relo section(17) .rel.eh_frame for section(16) .eh_frame

I compiled the program using clang and llc.

clang -S \
    -D __BPF_TRACING__ \
    -I/home/nhed/Development/ebpf-kill-example/src/../libbpf/src//root/usr/include/ \
    -Wall \
    -Werror \
    -O2 -emit-llvm -c -g kern.c
llc -march=bpf -filetype=obj -o kern.o kern.ll

The code results in the following assembly.

nhed@nhed-1:~/Development/ebpf-kill-example$ llvm-objdump -S src/kern.o

src/kern.o:	file format ELF64-BPF


Disassembly of section tracepoint/syscalls/sys_enter_kill:

0000000000000000 ebpf_kill_example:
;   if (ctx->sig != SIGKILL)
       0:	79 12 18 00 00 00 00 00	r2 = *(u64 *)(r1 + 24)
       1:	55 02 10 00 09 00 00 00	if r2 != 9 goto +16 <LBB0_2>
;   long key = labs(ctx->pid);
       2:	79 11 10 00 00 00 00 00	r1 = *(u64 *)(r1 + 16)
       3:	bf 12 00 00 00 00 00 00	r2 = r1
       4:	c7 02 00 00 3f 00 00 00	r2 s>>= 63
       5:	0f 21 00 00 00 00 00 00	r1 += r2
       6:	af 21 00 00 00 00 00 00	r1 ^= r2
       7:	7b 1a f8 ff 00 00 00 00	*(u64 *)(r10 - 8) = r1
       8:	b7 01 00 00 01 00 00 00	r1 = 1
;   int val = 1;
       9:	63 1a f4 ff 00 00 00 00	*(u32 *)(r10 - 12) = r1
      10:	bf a2 00 00 00 00 00 00	r2 = r10
;   long key = labs(ctx->pid);
      11:	07 02 00 00 f8 ff ff ff	r2 += -8
      12:	bf a3 00 00 00 00 00 00	r3 = r10
      13:	07 03 00 00 f4 ff ff ff	r3 += -12
;   bpf_map_update_elem(&kill_map, &key, &val, BPF_NOEXIST);
      14:	18 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00	r1 = 0 ll
      16:	b7 04 00 00 01 00 00 00	r4 = 1
      17:	85 00 00 00 02 00 00 00	call 2

0000000000000090 LBB0_2:
; }
      18:	b7 00 00 00 00 00 00 00	r0 = 0
      19:	95 00 00 00 00 00 00 00	exit

I load the program using bpf_prog_load and bpf_object__find_program_by_name.

Can you help me understand why these warnings occour and how I can fix them?

xsk_prod_nb_free

Who can explain the principle and implementation method of this function?

Or can someone recommend the article on AF_XDP source code?

I want to learn AF_XDP. But it's hard for me to read the af_xdp source code directly.

static inline __u32 xsk_prod_nb_free(struct xsk_ring_prod *r, __u32 nb)

bpf_create_map seems to be failing under UBSan

It was originally discovered by the systemd CI in systemd/systemd#12151:

../src/libbpf/bpf_next/src/libbpf/src/bpf.c:92:2: runtime error: null pointer passed as argument 2, which is declared to never be null
    #0 0x558b1dea3ecc in bpf_create_map_xattr ../src/libbpf/bpf_next/src/libbpf/src/bpf.c:92
    #1 0x558b1e2021db in bpf_create_map ../src/libbpf/bpf_next/src/libbpf/src/bpf.c:135
    #2 0x558b1e1ba512 in bpf_firewall_supported ../src/core/bpf-firewall.c:685
    #3 0x558b1df96a74 in cg_bpf_mask_supported ../src/core/cgroup.c:2531
    #4 0x558b1df9a04c in manager_setup_cgroup ../src/core/cgroup.c:2685
    #5 0x558b1deb044d in manager_new ../src/core/manager.c:835
    #6 0x558b1dea48a0 in main ../src/test/test-sched-prio.c:31
    #7 0x7f99c325d09a in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2409a)
    #8 0x558b1dea4089 in _start (/build/build/test-sched-prio+0x496089)

SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior ../src/libbpf/bpf_next/src/libbpf/src/bpf.c:92:2 in
-------

Can AF_XDP support multithread concurrent receive packet with a nic ring?

Currently, libbpf do not support concurrently receive pkts using AF_XDP.

For example: I create 4 af_xdp sockets on nic's ring 0. Four sockets receiving packets concurrently can't work correctly because the API of cq xsk_ring_prod__reserve and xsk_ring_prod__submit don't support concurrence.

So, my question is why libbpf was designed non-concurrent mode, is the limit of kernel or other reason? I want to change the code to support concurrent receive pkts, therefore I want to find out whether this is theoretically supported.

Thx.

Question about using BPF_MAP_TYPE_LPM_TRIE

I am trying to use BPF_MAP_TYPE_LPM_TRIE to implement subnet filtering. But I encounter some problems when I use the data structure.

I have my map defined in the bpf program as follow:

 72 struct bpf_map_def SEC("maps") block_subnet_map = {
 73   .type        = BPF_MAP_TYPE_LPM_TRIE,
 74   .key_size    = 8,
 75   .value_size  = sizeof(uint64_t), 
 76   .max_entries = 5120,
 77   .map_flags   = BPF_F_NO_PREALLOC,
 78 };

I was also trying to create a key for lookup:

345   struct bpf_lpm_trie_key lookup = {
346     .prefixlen = 32,
347     .data = {192, 168, 0, 0}
348   };

When I try to compile the code, the compiler says:

xdp_prog_kern.c:347:12: error: excess elements in array initializer [-Werror]
                .data = {192, 168, 0, 0}
                         ^~~

Does anyone how to solve this problem? Or what is the correct way to use BPF_MAP_TYPE_LPM_TRIE because I cannot find too much information about how to use it? I appreciate your help!

Tagging versions

Not really an issue, more of a question: is there a plan to set a version independent of the kernel (separate from the ABI revision) and tag it on Github when a release happen?

Thanks!

Why does libbpf hide `struct xsk_umem` thus preventing XDP_SHARED_UMEM?

I want to try XDP_SHARED_UMEM: https://www.kernel.org/doc/html/latest/networking/af_xdp.html#xdp-shared-umem-bind-flag

So what the article says is, that in case one wants to use this feature he has to set XDP_SHARED_UMEM option and provide the original fd of the socket via a struct sockaddr_xdp sxdp.

I took a look at xsk.c. The function xsk_socket__create does this for the user of the library by checking umem->refcount. In order for this to work, two or more programs need the same struct xsk_umem.

In my "architecture" I have this main program which loads the AF-XDP kernel program, sets up a shared memory and then launches several other programs depending on how many packet streams have to be processed - each one with their own AF-XDP socket.

My original idea was to create a separate program (the one who manages the UMEM) which also opens the first AF-XDP socket and every other program then uses this socket and its umem as SHARED_UMEM. So I thought that this manage-program would copy the content of its struct xsk_umem into the shared memory and then all other sub-processes can load this shared-memory and pass it to their call of xsk_socket__create.

But I don't think that's possible because the definition of struct xsk_umem is hidden in xsk.c.

How do you expect a user of your library to implement the XDP_SHARED_UMEM feature?

libbpf fais to compile with gcc 8.3 after the last sync

After the latest sync in #85 libbpf fails to compile with gcc 8.3 in Debian containers:

make: Entering directory '/build/src'
mkdir -p ../build/staticobjs
gcc-8 -I. -I../include -I../include/uapi -g -O2 -Werror -Wall -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64   -c bpf.c -o ../build/staticobjs/bpf.o
gcc-8 -I. -I../include -I../include/uapi -g -O2 -Werror -Wall -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64   -c btf.c -o ../build/staticobjs/btf.o
gcc-8 -I. -I../include -I../include/uapi -g -O2 -Werror -Wall -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64   -c libbpf.c -o ../build/staticobjs/libbpf.o
libbpf.c: In function 'libbpf_prog_type_by_name.part.29':
libbpf.c:4692:4: error: 'strncat' specified bound 118 equals destination size [-Werror=stringop-truncation]
    strncat(dst, name + section_names[i].len,
    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     sizeof(raw_tp_btf_name) - (dst - raw_tp_btf_name));
     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
libbpf.c:4692:4: error: 'strncat' specified bound 118 equals destination size [-Werror=stringop-overflow=]
cc1: all warnings being treated as errors
make: *** [Makefile:100: ../build/staticobjs/libbpf.o] Error 1
make: Leaving directory '/build/src'

Dash in filename prevents bpf object file from loading

If file is named with dash, for example, "b-lah.o",
the following code:

rc = bpf_prog_load("bpf/b-lah.o", BPF_PROG_TYPE_SOCKET_FILTER, &pobj, &prog_fd);

fails with:

libbpf: failed to create map (name: 'b-lah.rodata'): Invalid argument(-22)
libbpf: failed to load object 'bpf/b-lah.o'

Just renaming the file to "blah.o" makes it load fine.

To reproduce the issue, the function call (probably with arguments) is required;
Example file:

$ cat bpf-prog.c 

#include <linux/bpf.h>
#include <bpf/bpf_helpers.h>

#include <linux/in.h>
#include <linux/types.h>
#include <linux/string.h>
#include <linux/if_ether.h>
#include <linux/if_packet.h>
#include <linux/ip.h>
#include <linux/tcp.h>
#include <linux/udp.h>


SEC("socket")
int tryme(struct __sk_buff *skb)
{
    const char buf[10] = "foo:%d!\n";
    bpf_trace_printk(buf, sizeof(buf), 3); // if this line is commented, works
    return 0;
}

char _license[] SEC("license") = "GPL";

libbpf-0.0.6 is used on gentoo with 5.5.2 kernel

multiple BPF programs with the same section name seems doesn't work

Hi @anakryiko ,

I tried
https://github.com/torvalds/linux/blob/v5.10-rc6/tools/testing/selftests/bpf/prog_tests/subprogs.c
https://github.com/torvalds/linux/blob/v5.10-rc6/tools/testing/selftests/bpf/progs/test_subprogs.c
with
https://github.com/libbpf/libbpf-bootstrap (and use v0.2 libbpf)
But got subprogs.skel.h like this:

struct subprogs_bpf {
        struct bpf_object_skeleton *skeleton;
        struct bpf_object *obj;
        struct {
                struct bpf_map *bss;
        } maps;
        struct {
                struct bpf_program *prog1;
                struct bpf_program *prog2;
        } progs;
        struct {
                struct bpf_link *prog1;
                struct bpf_link *prog2;
        } links;
        struct subprogs_bpf__bss {
                int res1;
                int res2;
                int res3;
                int res4;
        } *bss;
};

Without prog3 and prog4, the subprog.c looks like:

int main(int argc, char **argv)
{
	struct subprogs_bpf *skel;
	int err;

	libbpf_set_print(libbpf_print_fn);

	bump_memlock_rlimit();

	skel = subprogs_bpf__open_and_load();
	if (!skel) {
		fprintf(stderr, "Failed to open and load BPF skeleton\n");
		return 1;
	}

	err = subprogs_bpf__attach(skel);
	if (err) {
		fprintf(stderr, "Failed to attach BPF skeleton\n");
		goto cleanup;
	}

	printf("Successfully started!\n");

	for (;;) {
		fprintf(stderr, ".");
		sleep(1);
	}

cleanup:
	subprogs_bpf__destroy(skel);
	return -err;
}

Then in tools/testing/selftests/bpf, after make, I can get test_subprogs.skel.h like this:

struct test_subprogs {
        struct bpf_object_skeleton *skeleton;
        struct bpf_object *obj;
        struct {
                struct bpf_map *bss;
        } maps;
        struct {
                struct bpf_program *prog1;
                struct bpf_program *prog3;
                struct bpf_program *prog2;
                struct bpf_program *prog4;
        } progs;
        struct {
                struct bpf_link *prog1;
                struct bpf_link *prog3;
                struct bpf_link *prog2;
                struct bpf_link *prog4;
        } links;
        struct test_subprogs__bss {
                int res1;
                int res2;
                int res3;
                int res4;
        } *bss;
};

Am I missed sth?

undefined reference to symbol 'gzopen64@@ZLIB_1.2.3.3'

I am compiling this tutorial: https://github.com/xdp-project/xdp-tutorial/tree/master/advanced03-AF_XDP

but I replaced the libbpf-folder with the content of this repository. Everything compiles fine until this error:

/usr/bin/ld: ../libbpf/src/libbpf.a(libbpf.o): undefined reference to symbol 'gzopen64@@ZLIB_1.2.3.3'
//lib/x86_64-linux-gnu/libz.so.1: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status
../common/common.mk:107: recipe for target 'af_xdp_user' failed

Any ideas?

The tutorial code compiles fine with libbpf as a submodule (as xdp-tutorial is supplying it)

libbpf invalid arg

Hi Dear Owner/Mantainers:

I am running a bpftool command and encounter below error:

 sudo bpftool prog load bpf_sockops_v4.o /sys/fs/bpf/bpf_sockops
libbpf: Error loading BTF: Invalid argument(22)
libbpf: magic: 0xeb9f
version: 1
flags: 0x0
hdr_len: 24
type_off: 0
type_len: 952
str_off: 952
str_len: 1192
btf_total_size: 2168
[1] PTR (anon) type_id=2
[2] STRUCT bpf_sock_ops size=192 vlen=36
        op type_id=3 bits_offset=0
        (anon) type_id=5 bits_offset=32
        family type_id=3 bits_offset=160
        remote_ip4 type_id=3 bits_offset=192
        local_ip4 type_id=3 bits_offset=224
        remote_ip6 type_id=6 bits_offset=256
        local_ip6 type_id=6 bits_offset=384
        remote_port type_id=3 bits_offset=512
        local_port type_id=3 bits_offset=544
        is_fullsock type_id=3 bits_offset=576
        snd_cwnd type_id=3 bits_offset=608
        srtt_us type_id=3 bits_offset=640
        bpf_sock_ops_cb_flags type_id=3 bits_offset=672
        state type_id=3 bits_offset=704
        rtt_min type_id=3 bits_offset=736
        snd_ssthresh type_id=3 bits_offset=768
        rcv_nxt type_id=3 bits_offset=800
        snd_nxt type_id=3 bits_offset=832
        snd_una type_id=3 bits_offset=864
        mss_cache type_id=3 bits_offset=896
        ecn_flags type_id=3 bits_offset=928
        rate_delivered type_id=3 bits_offset=960
        rate_interval_us type_id=3 bits_offset=992
        packets_out type_id=3 bits_offset=1024
        retrans_out type_id=3 bits_offset=1056
        total_retrans type_id=3 bits_offset=1088
        segs_in type_id=3 bits_offset=1120
        data_segs_in type_id=3 bits_offset=1152
        segs_out type_id=3 bits_offset=1184
        data_segs_out type_id=3 bits_offset=1216
        lost_out type_id=3 bits_offset=1248
        sacked_out type_id=3 bits_offset=1280
        sk_txhash type_id=3 bits_offset=1312
        bytes_received type_id=8 bits_offset=1344
        bytes_acked type_id=8 bits_offset=1408
        (anon) type_id=10 bits_offset=1472
[3] TYPEDEF __u32 type_id=4
[4] INT unsigned int size=4 bits_offset=0 nr_bits=32 encoding=(none)
[5] UNION (anon) size=16 vlen=3
        args type_id=6 bits_offset=0
        reply type_id=3 bits_offset=0
        replylong type_id=6 bits_offset=0
[6] ARRAY (anon) type_id=3 index_type_id=7 nr_elems=4
[7] INT __ARRAY_SIZE_TYPE__ size=4 bits_offset=0 nr_bits=32 encoding=(none)
[8] TYPEDEF __u64 type_id=9
[9] INT long long unsigned int size=8 bits_offset=0 nr_bits=64 encoding=(none)
[10] UNION (anon) size=8 vlen=1
        sk type_id=11 bits_offset=0
[11] PTR (anon) type_id=26
[12] FUNC_PROTO (anon) return=13 args=(1 skops)
[13] INT int size=4 bits_offset=0 nr_bits=32 encoding=SIGNED
[14] FUNC bpf_sockops_v4 type_id=12 vlen != 0

libbpf: Error loading .BTF into kernel: -22.
libbpf: bad map relo against section 5
Error: failed to open object file

and I think it is caused by libbpf, and I am not facing same issue on an ubuntu 20.10 without bcc/libbpf installed.

below is my setup's information, could you please point out where is wrong or how to debug or how to remove the bcc/libbpf to give a try? Thanks in advance.

[root@centos8-worker3 sockredir]# clang --version
clang version 11.0.0 (https://github.com/llvm/llvm-project.git 176249bd6732a8044d457092ed932768724a6f06)
Target: x86_64-unknown-linux-gnu
Thread model: posix
InstalledDir: /usr/local/bin

[root@centos8-worker3 sockredir]# llc --version
LLVM (http://llvm.org/):
  LLVM version 11.0.0
  DEBUG build with assertions.
  Default target: x86_64-unknown-linux-gnu
  Host CPU: cascadelake

[root@centos8-worker3 sockredir]# ip -V
ip utility, iproute2-5.8.0

[root@centos8-worker3 sockredir]# uname -r
4.18.0-193.19.1.el8_2.x86_64

[root@centos8-worker3 libbpf-tools]# pahole --version
v1.17

[root@centos8-worker3 libbpf-tools]# cat /boot/config-4.18.0-193.el8.x86_64 | grep BTF
CONFIG_DEBUG_INFO_BTF=y

//this seems fine, I exported it 
[root@centos8-worker3 libbpf-tools]# ll /sys/kernel/btf/vmlinux
-r--r--r--. 1 root root 1831174 Nov 16 23:49 /sys/kernel/btf/vmlinux

and the object is like this:

[root@centos8-worker3 sockredir]# readelf -S bpf_sockops_v4.o
There are 25 section headers, starting at offset 0x3200:

Section Headers:
  [Nr] Name              Type             Address           Offset
       Size              EntSize          Flags  Link  Info  Align
  [ 0]                   NULL             0000000000000000  00000000
       0000000000000000  0000000000000000           0     0     0
  [ 1] .strtab           STRTAB           0000000000000000  000030e1
       000000000000011f  0000000000000000           0     0     1
  [ 2] .text             PROGBITS         0000000000000000  00000040
       0000000000000000  0000000000000000  AX       0     0     4
  [ 3] "sockops"         PROGBITS         0000000000000000  00000040
       0000000000000268  0000000000000000  AX       0     0     8
  [ 4] .rel"sockops"     REL              0000000000000000  00002720
       0000000000000010  0000000000000010          24     3     8
  [ 5] "maps"            PROGBITS         0000000000000000  000002a8
       0000000000000014  0000000000000000  WA       0     0     4
  [ 6] "license"         PROGBITS         0000000000000000  000002bc
       0000000000000004  0000000000000000  WA       0     0     1
  [ 7] "version"         PROGBITS         0000000000000000  000002c0
       0000000000000004  0000000000000000  WA       0     0     4
  [ 8] .rodata.str1.1    PROGBITS         0000000000000000  000002c4
       0000000000000044  0000000000000001 AMS       0     0     1
  [ 9] .debug_loc        PROGBITS         0000000000000000  00000308
       00000000000000c2  0000000000000000           0     0     1
  [10] .debug_abbrev     PROGBITS         0000000000000000  000003ca
       00000000000001b4  0000000000000000           0     0     1
  [11] .debug_info       PROGBITS         0000000000000000  0000057e
       0000000000000649  0000000000000000           0     0     1
  [12] .rel.debug_info   REL              0000000000000000  00002730
       00000000000007c0  0000000000000010          24    11     8
  [13] .debug_ranges     PROGBITS         0000000000000000  00000bc7
       0000000000000030  0000000000000000           0     0     1
  [14] .debug_str        PROGBITS         0000000000000000  00000bf7
       0000000000000428  0000000000000001  MS       0     0     1
  [15] .BTF              PROGBITS         0000000000000000  0000101f
       0000000000000878  0000000000000000           0     0     1
  [16] .rel.BTF          REL              0000000000000000  00002ef0
       0000000000000030  0000000000000010          24    15     8
  [17] .BTF.ext          PROGBITS         0000000000000000  00001897
       00000000000001c0  0000000000000000           0     0     1
  [18] .rel.BTF.ext      REL              0000000000000000  00002f20
       0000000000000190  0000000000000010          24    17     8
  [19] .debug_frame      PROGBITS         0000000000000000  00001a58
       0000000000000028  0000000000000000           0     0     8
  [20] .rel.debug_frame  REL              0000000000000000  000030b0
       0000000000000020  0000000000000010          24    19     8
  [21] .debug_line       PROGBITS         0000000000000000  00001a80
       000000000000021a  0000000000000000           0     0     1
  [22] .rel.debug_line   REL              0000000000000000  000030d0
       0000000000000010  0000000000000010          24    21     8
  [23] .llvm_addrsig     LOOS+0xfff4c03   0000000000000000  000030e0
       0000000000000001  0000000000000000   E      24     0     1
  [24] .symtab           SYMTAB           0000000000000000  00001ca0
       0000000000000a80  0000000000000018           1   108     8
Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
  L (link order), O (extra OS processing required), G (group), T (TLS),
  C (compressed), x (unknown), o (OS specific), E (exclude),
  p (processor specific)

fails to build for ARM

libbpf assumes that off_t is 64 bit but that's not true by default on ARM, so building fails with:

In file included from xsk.c:22:
xsk.c: In function 'xsk_umem__create_v0_0_4':
../include/uapi/linux/if_xdp.h:91:34: error: overflow in conversion from 'long long unsigned int' to '__off_t' {aka 'long int'} changes value from '4294967296' to '0' [-Werror=overflow]
xsk.c:202:6: note: in expansion of macro 'XDP_UMEM_PGOFF_FILL_RING'
../include/uapi/linux/if_xdp.h:92:40: error: overflow in conversion from 'long long unsigned int' to '__off_t' {aka 'long int'} changes value from '6442450944' to '-2147483648' [-Werror=overflow]
xsk.c:219:6: note: in expansion of macro 'XDP_UMEM_PGOFF_COMPLETION_RING'
cc1: all warnings being treated as errors
make: *** [Makefile:100: staticobjs/xsk.o] Error 1

-D_FILE_OFFSET_BITS=64 is needed for a 64 bit off_t.

-EBUSY with some selftests on 5.7-rcX

(Are you OK with questions/reports here or prefer bpf@vger?)

I'm testing BPF LSM and wanted to very my setup by running the test_lsm selftests (./test_progs -vv -t test_lsm) but it fails:

libbpf: loading object 'lsm' from buffer
libbpf: section(1) .strtab, size 306, link 0, flags 0, type=3
libbpf: skip section(1) .strtab
libbpf: section(2) .text, size 0, link 0, flags 6, type=1
libbpf: skip section(2) .text
libbpf: section(3) lsm/file_mprotect, size 192, link 0, flags 6, type=1
libbpf: found program lsm/file_mprotect
libbpf: section(4) .rellsm/file_mprotect, size 32, link 25, flags 0, type=9
libbpf: section(5) lsm/bprm_committed_creds, size 104, link 0, flags 6, type=1
libbpf: found program lsm/bprm_committed_creds
libbpf: section(6) .rellsm/bprm_committed_creds, size 32, link 25, flags 0, type=9
libbpf: section(7) license, size 4, link 0, flags 3, type=1
libbpf: license of lsm is GPL
libbpf: section(8) .bss, size 12, link 0, flags 3, type=8
libbpf: section(9) .debug_str, size 133448, link 0, flags 30, type=1
libbpf: skip section(9) .debug_str
libbpf: section(10) .debug_loc, size 428, link 0, flags 0, type=1
libbpf: skip section(10) .debug_loc
libbpf: section(11) .rel.debug_loc, size 112, link 25, flags 0, type=9
libbpf: skip relo .rel.debug_loc(11) for section(10)
libbpf: section(12) .debug_abbrev, size 901, link 0, flags 0, type=1
libbpf: skip section(12) .debug_abbrev
libbpf: section(13) .debug_info, size 223699, link 0, flags 0, type=1
libbpf: skip section(13) .debug_info
libbpf: section(14) .rel.debug_info, size 112, link 25, flags 0, type=9
libbpf: skip relo .rel.debug_info(14) for section(13)
libbpf: section(15) .debug_ranges, size 96, link 0, flags 0, type=1
libbpf: skip section(15) .debug_ranges
libbpf: section(16) .rel.debug_ranges, size 128, link 25, flags 0, type=9
libbpf: skip relo .rel.debug_ranges(16) for section(15)
libbpf: section(17) .BTF, size 5421, link 0, flags 0, type=1
libbpf: section(18) .rel.BTF, size 64, link 25, flags 0, type=9
libbpf: skip relo .rel.BTF(18) for section(17)
libbpf: section(19) .BTF.ext, size 484, link 0, flags 0, type=1
libbpf: section(20) .rel.BTF.ext, size 416, link 25, flags 0, type=9
libbpf: skip relo .rel.BTF.ext(20) for section(19)
libbpf: section(21) .debug_frame, size 64, link 0, flags 0, type=1
libbpf: skip section(21) .debug_frame
libbpf: section(22) .rel.debug_frame, size 32, link 25, flags 0, type=9
libbpf: skip relo .rel.debug_frame(22) for section(21)
libbpf: section(23) .debug_line, size 227, link 0, flags 0, type=1
libbpf: skip section(23) .debug_line
libbpf: section(24) .rel.debug_line, size 32, link 25, flags 0, type=9
libbpf: skip relo .rel.debug_line(24) for section(23)
libbpf: section(25) .symtab, size 288, link 1, flags 0, type=2
libbpf: looking for externs among 12 symbols...
libbpf: collected 0 externs total
libbpf: map 'lsm.bss' (global data): at sec_idx 8, offset 0, flags 400.
libbpf: map 0 is "lsm.bss"
libbpf: collecting relocating info for: 'lsm/file_mprotect'
libbpf: relo for shdr 8, symb 8, value 0, type 1, bind 1, name 232 ('monitored_pid'), insn 12
libbpf: found data map 0 (lsm.bss, sec 8, off 0) for insn 12
libbpf: relo for shdr 8, symb 9, value 4, type 1, bind 1, name 34 ('mprotect_count'), insn 17
libbpf: found data map 0 (lsm.bss, sec 8, off 0) for insn 17
libbpf: collecting relocating info for: 'lsm/bprm_committed_creds'
libbpf: relo for shdr 8, symb 8, value 0, type 1, bind 1, name 232 ('monitored_pid'), insn 1
libbpf: found data map 0 (lsm.bss, sec 8, off 0) for insn 1
libbpf: relo for shdr 8, symb 7, value 8, type 1, bind 1, name 49 ('bprm_count'), insn 6
libbpf: found data map 0 (lsm.bss, sec 8, off 0) for insn 6
libbpf: loading kernel BTF '/sys/kernel/btf/vmlinux': 0
libbpf: created map lsm.bss: fd=4
libbpf: loading kernel BTF '/sys/kernel/btf/vmlinux': 0
libbpf: prog 'lsm/file_mprotect': performing 4 CO-RE offset relocs
libbpf: prog 'lsm/file_mprotect': relo #0: kind 0, spec is [6] vm_area_struct + 0:6 => 64.0 @ &x[0].vm_mm
libbpf: [6] vm_area_struct: found candidate [465] vm_area_struct
libbpf: prog 'lsm/file_mprotect': relo #0: matching candidate #0 vm_area_struct against spec [465] vm_area_struct + 0:6 => 64.0 @ &x[0].vm_mm: 1
libbpf: prog 'lsm/file_mprotect': relo #0: patched insn #5 (LDX/ST/STX) off 64 -> 64
libbpf: prog 'lsm/file_mprotect': relo #1: kind 0, spec is [31] mm_struct + 0:0:35 => 304.0 @ &x[0].start_stack
libbpf: [31] mm_struct: found candidate [260] mm_struct
libbpf: prog 'lsm/file_mprotect': relo #1: matching candidate #0 mm_struct against spec [260] mm_struct + 0:0:35 => 304.0 @ &x[0].start_stack: 1
libbpf: prog 'lsm/file_mprotect': relo #1: patched insn #7 (LDX/ST/STX) off 304 -> 304
libbpf: prog 'lsm/file_mprotect': relo #2: kind 0, spec is [6] vm_area_struct + 0:0 => 0.0 @ &x[0].vm_start
libbpf: prog 'lsm/file_mprotect': relo #2: matching candidate #0 vm_area_struct against spec [465] vm_area_struct + 0:0 => 0.0 @ &x[0].vm_start: 1
libbpf: prog 'lsm/file_mprotect': relo #2: patched insn #8 (LDX/ST/STX) off 0 -> 0
libbpf: prog 'lsm/file_mprotect': relo #3: kind 0, spec is [6] vm_area_struct + 0:1 => 8.0 @ &x[0].vm_end
libbpf: prog 'lsm/file_mprotect': relo #3: matching candidate #0 vm_area_struct against spec [465] vm_area_struct + 0:1 => 8.0 @ &x[0].vm_end: 1
libbpf: prog 'lsm/file_mprotect': relo #3: patched insn #10 (LDX/ST/STX) off 8 -> 8
test_test_lsm:PASS:skel_load 0 nsec
libbpf: program 'lsm/file_mprotect': failed to attach: Device or resource busy
libbpf: failed to auto-attach program 'test_int_hook': -16
test_test_lsm:FAIL:attach lsm attach failed: -16
#70 test_lsm:FAIL
Summary: 0/0 PASSED, 0 SKIPPED, 1 FAILED

I get -EBUSY with fentry_fexit too:

# ./test_progs -t fentry_fexit
test_fentry_fexit:PASS:fentry_skel_load 0 nsec
test_fentry_fexit:PASS:fexit_skel_load 0 nsec
libbpf: program 'fentry/bpf_fentry_test1': failed to attach: Device or resource busy
libbpf: failed to auto-attach program 'test1': -16
test_fentry_fexit:FAIL:fentry_attach fentry attach failed: -16
#13 fentry_fexit:FAIL
Summary: 0/0 PASSED, 0 SKIPPED, 1 FAILED

However, btf_dump is OK:

# ./test_progs -t btf_dump
#5/1 btf_dump: syntax:OK
#5/2 btf_dump: ordering:OK
#5/3 btf_dump: padding:OK
#5/4 btf_dump: packing:OK
#5/5 btf_dump: bitfields:OK
#5/6 btf_dump: multidim:OK
#5/7 btf_dump: namespacing:OK
#5 btf_dump:OK
Summary: 1/7 PASSED, 0 SKIPPED, 0 FAILED

Any feedback what to check?

# clang --version
clang version 10.0.0
Target: x86_64-generic-linux
Thread model: posix
InstalledDir: /usr/bin
# pahole --version
v1.16

5.7-rc3

libbpf: failed to open perf buffer event on cpu

I'm using Ubuntu 64-bit with Linux kernel 5.0.0-37-generic. I'm running a BPF program which uses a perf_event_array whose id on the BPF VM is 14. When trying to inspect it using bpftool map event_pipe id 14 i get the following error:
libbpf: failed to open perf buffer event on cpu #4: No such device Error: failed to create perf buffer: Unknown error -19 (-19)
My machine has 4 cpus online, but 128 possible (e.g /sys/devices/system/cpu/possible contains "0-127")
I guess the problem is that libbpf reads from /sys/devices/system/cpu/possible instead of /sys/devices/system/cpu/online and thus thinks that it needs to attach to 128 cpus instead of just 4.

pb->cpu_cnt = libbpf_num_possible_cpus();

Using libbpf without CO-RE

I'm developing a tool which is now based on BCC, and would like to make the move to libbpf.
I need the tool to support a minimal kernel version 4.14, which doesn't have CO-RE.

I have read the guide https://facebookmicrosites.github.io/bpf/blog/2020/02/20/bcc-to-libbpf-howto-guide.html,
and took a look at the libbpf-tools of bcc, but both only deal with kernels with CO-RE support, and I failed to modify them to run on a 4.14 kernel.

Although some of the bpf samples in the kernel source don't use CO-RE, they all use bpf_load.h,
and require having dependencies on the tools dir, which I would like to avoid.

I would appreciate if someone can provide with a working example of using libbpf without co-re.
Specifically, I'm looking for an example makefile, and to know how to load my bpf code with libbpf.

Thanks,
Yaniv

Undefined reference to hashmap

I get a linker error:

/usr/lib/gcc/x86_64-linux-gnu/7/../../../../lib/libbpf.so: undefined reference to `hashmap__insert'
/usr/lib/gcc/x86_64-linux-gnu/7/../../../../lib/libbpf.so: undefined reference to `hashmap(float, long double,...)(...)'
/usr/lib/gcc/x86_64-linux-gnu/7/../../../../lib/libbpf.so: undefined reference to `hashmap__new'

Shouldn't hashmap.c be included in the OBJS list:
https://github.com/libbpf/libbpf/blob/master/src/Makefile#L36-L37
?

Facing issue while building libbpf

I'm trying to build libbpf on centos 7 with kernel verison:
[root@localhost portablebpf]# uname -r
3.10.0-514.el7.x86_64

I'm getting following compilation error, I can understand the some of these feature might not be supported by underline kernel.
e.g.PERF_EVENT_IOC_SET_BPF added in linux 4.1(https://elixir.bootlin.com/linux/v4.1.52/A/ident/PERF_EVENT_IOC_SET_BPF) so it will not work on my linux kernel

However the cause of second compilation error is that PERF_COUNT_SW_BPF_OUTPUT is not available in 3.10 and got added in kernel version 4.4 (https://elixir.bootlin.com/linux/v4.4.260/A/ident/PERF_COUNT_SW_BPF_OUTPUT)

My questions is what would be minimum kernel version on which libbpf would work w/o any issue? considering the fact it depends on the various kernel features.

root@localhost src]# make
MKDIR staticobjs
CC bpf.o
CC btf.o
CC libbpf.o
libbpf.c: In function ‘bpf_program__attach_perf_event’:
libbpf.c:9543:17: error: ‘PERF_EVENT_IOC_SET_BPF’ undeclared (first use in this function); did you mean ‘PERF_EVENT_IOC_ENABLE’?
if (ioctl(pfd, PERF_EVENT_IOC_SET_BPF, prog_fd) < 0) {
^~~~~~~~~~~~~~~~~~~~~~
PERF_EVENT_IOC_ENABLE
libbpf.c:9543:17: note: each undeclared identifier is reported only once for each function it appears in
libbpf.c: In function ‘perf_buffer__new’:
libbpf.c:10313:16: error: ‘PERF_COUNT_SW_BPF_OUTPUT’ undeclared (first use in this function); did you mean ‘PERF_COUNT_SW_CPU_CLOCK’?
attr.config = PERF_COUNT_SW_BPF_OUTPUT;
^~~~~~~~~~~~~~~~~~~~~~~~
PERF_COUNT_SW_CPU_CLOCK
make: *** [staticobjs/libbpf.o] Error 1

possible dereference of NULL pointer

I'm not a full-time C programmer, so apologies in advance if this is incorrect.

I've been examining the CO-RE code in libbpf, and I believe I have a found a NULL pointer dereference.
In the skip_mods_and_typedefs function:

libbpf/src/libbpf.c

Lines 1828 to 1843 in 66780a4

static const struct btf_type *
skip_mods_and_typedefs(const struct btf *btf, __u32 id, __u32 *res_id)
{
const struct btf_type *t = btf__type_by_id(btf, id);
if (res_id)
*res_id = id;
while (btf_is_mod(t) || btf_is_typedef(t)) {
if (res_id)
*res_id = t->type;
t = btf__type_by_id(btf, t->type);
}
return t;
}

it calls btf__type_by_id which may return NULL if the type_id argument is invalid.

libbpf/src/btf.c

Lines 214 to 220 in 66780a4

const struct btf_type *btf__type_by_id(const struct btf *btf, __u32 type_id)
{
if (type_id > btf->nr_types)
return NULL;
return btf->types[type_id];
}

skip_mods_and_typedefs proceeds to call is_mod

libbpf/src/btf.h

Lines 206 to 213 in 66780a4

static inline bool btf_is_mod(const struct btf_type *t)
{
__u16 kind = btf_kind(t);
return kind == BTF_KIND_VOLATILE ||
kind == BTF_KIND_CONST ||
kind == BTF_KIND_RESTRICT;
}

and deeper btf_kind

libbpf/src/btf.h

Lines 124 to 127 in 66780a4

static inline __u16 btf_kind(const struct btf_type *t)
{
return BTF_INFO_KIND(t->info);
}

which accesses t->info.

Since t at this point will be NULL, wouldn't this be a NULL pointer dereference?

clang seems to be failing to compile libbpf

It was originally discovered by the systemd CI in systemd/systemd#12151:

FAILED: src/libbpf/9e6d599@@bpf@sta/bpf_next_src_libbpf_src_libbpf.c.o
clang -Isrc/libbpf/9e6d599@@bpf@sta -Isrc/libbpf -I../src/libbpf -I../src/libbpf/bpf_next/src/libbpf/include -I../src/libbpf/bpf_next/src/libbpf/include/uapi -Xclang -fcolor-diagnostics -fsanitize=address,undefined -fno-omit-frame-pointer -pipe -D_FILE_OFFSET_BITS=64 -Wall -Winvalid-pch -Werror -std=gnu99 -g -Wextra -Werror=undef -Wmissing-include-dirs -Wold-style-definition -Wpointer-arith -Winit-self -Wfloat-equal -Werror=missing-prototypes -Werror=implicit-function-declaration -Werror=missing-declarations -Werror=return-type -Werror=incompatible-pointer-types -Werror=format=2 -Wstrict-prototypes -Wredundant-decls -Wmissing-noreturn -Wshadow -Wendif-labels -Wstrict-aliasing=2 -Wwrite-strings -Werror=overflow -Werror=shift-count-overflow -Wdate-time -Wnested-externs -Wno-unused-parameter -Wno-missing-field-initializers -Wno-unused-result '-Wno-error=#warnings' -Wno-string-plus-int -Wno-error=nonnull -ffast-math -fno-common -fdiagnostics-show-option -fno-strict-aliasing -fvisibility=hidden -fstack-protector -fstack-protector-strong --param=ssp-buffer-size=4 -Wno-typedef-redefinition -Wno-gnu-variable-sized-type-not-at-end -Werror=shadow -include config.h -fPIC -g -O2 -Werror -Wall -Wno-pointer-arith -Wno-sign-compare  -MD -MQ 'src/libbpf/9e6d599@@bpf@sta/bpf_next_src_libbpf_src_libbpf.c.o' -MF 'src/libbpf/9e6d599@@bpf@sta/bpf_next_src_libbpf_src_libbpf.c.o.d' -o 'src/libbpf/9e6d599@@bpf@sta/bpf_next_src_libbpf_src_libbpf.c.o' -c ../src/libbpf/bpf_next/src/libbpf/src/libbpf.c
../src/libbpf/bpf_next/src/libbpf/src/libbpf.c:63:26: error: format string is not a string literal [-Werror,-Wformat-nonliteral]
        return vfprintf(stderr, format, args);
                                ^~~~~~
1 error generated.

libbpf seems to be failing to compile on i386

This was originally found by the systemd CI in systemd/systemd#12306 (which is systemd/systemd#12151 with the submodule updated):

FAILED: subprojects/libbpf/b1a3e59@@bpf@sta/src_libbpf.c.o
cc -Isubprojects/libbpf/b1a3e59@@bpf@sta -Isubprojects/libbpf -I../subprojects/libbpf -I../subprojects/libbpf/./include -I../subprojects/libbpf/./include/uapi -flto -fdiagnostics-color=always -pipe -D_FILE_OFFSET_BITS=64 -std=gnu99 -g -O2 -fdebug-prefix-map=/tmp/autopkgtest.G3gX6Y/build.CIb/systemd=. -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 -fPIC -g -O2 -Werror -Wall -Wno-pointer-arith -Wno-sign-compare  -MD -MQ 'subprojects/libbpf/b1a3e59@@bpf@sta/src_libbpf.c.o' -MF 'subprojects/libbpf/b1a3e59@@bpf@sta/src_libbpf.c.o.d' -o 'subprojects/libbpf/b1a3e59@@bpf@sta/src_libbpf.c.o' -c ../subprojects/libbpf/src/libbpf.c
In file included from ../subprojects/libbpf/src/libbpf.c:46:0:
../subprojects/libbpf/src/libbpf.c: In function ‘bpf_object__init_internal_map’:
../subprojects/libbpf/src/libbpf_util.h:19:22: error: format ‘%ld’ expects argument of type ‘long int’, but argument 3 has type ‘int’ [-Werror=format=]
  libbpf_print(level, "libbpf: " fmt, ##__VA_ARGS__); \
                      ^
../subprojects/libbpf/src/libbpf_util.h:24:28: note: in expansion of macro ‘__pr’
 #define pr_debug(fmt, ...) __pr(LIBBPF_DEBUG, fmt, ##__VA_ARGS__)
                            ^~~~
../subprojects/libbpf/src/libbpf.c:820:2: note: in expansion of macro ‘pr_debug’
  pr_debug("map %ld is \"%s\"\n", map - obj->maps, map->name);
  ^~~~~~~~
../subprojects/libbpf/src/libbpf.c:820:18: note: format string is defined here
  pr_debug("map %ld is \"%s\"\n", map - obj->maps, map->name);
                ~~^
                %d
cc1: all warnings being treated as errors
ninja: build stopped: subcommand failed.

The full log can be found at https://objectstorage.prodstack4-5.canonical.com/v1/AUTH_77e2ada1e7a84929a74ba3b87153c0ac/autopkgtest-bionic-upstream-systemd-ci-systemd-ci/bionic/i386/s/systemd-upstream/20190413_164919_657f8@/log.gz

libbpf doesn't have attach_tracepoint

Someone (possibly me) needs to add bpf_attach_tracepoint support to libbpf. This is one of the things missing here compared to BCC's libbpf.

Is anyone else working on this? Thanks

0.0.9: missing declaratios in header files

Installed in $(ncludedir)/bpf header files do not provide all necessary declarations.
For example in bpf.h is:

[tkloczko@barrel bpf]$ grep bpf_stats_type *
bpf.h:LIBBPF_API int bpf_enable_stats(enum bpf_stats_type type);

That bpf_stats_type is source tree:

[tkloczko@barrel libbpf-0.0.9]$ grep bpf_stats_type -r
include/uapi/linux/bpf.h:enum bpf_stats_type {
src/bpf.c:int bpf_enable_stats(enum bpf_stats_type type)
src/bpf.h:LIBBPF_API int bpf_enable_stats(enum bpf_stats_type type);

however include/uapi/linux/bpf.h is not installed.

drop some packets before redirecting to userspace

For new version of libbpf in kernel was removed xdpsock_kern.c . So i saw bpf alu like code for loading on NIC. Can i write some xdp code for kernel and turn it into struct bpf_insn or something like this? Or same way i can not get performance?

Mismatch in versioning?

Latest git tag it is v0.3 however in src/libbpf.map is used used three digit versioning like LIBBPF_0.3.0

libbpf 1.0: support multiple .rodata*, .data*, .bss* sections

Support multiple .rodata/.data/.bss sections. Create separate backing BPF_MAP_TYPE_ARRAY for each. This will finally get rid of annoying

libbpf: elf: skipping unrecognized data section(8) .rodata.str1.1

warning. It will also support passing string literals to bpf_trace_printg():

bpf_printk("%s, %s!", "Hello", "world");

Having the ability to use multiple .data sections and putting dedicated global variables into separate .data.custom section also opens up some new and interesting possibilities (like dynamically sizing global arrays, without using BPF_MAP_TYPE_ARRAY map).

Release 0.3.0

Hi,

Some users of libbpf are making use of new symbols from the yet unreleased libbpf 0.3.0 in their released, stable versions - which is unfortunate.
Now that kernel 5.10 is out and there's a fair few new APIs, would it be possible to do a new release? The deadline for Debian 11 is fast approaching, so it would be really great if that was possible.

Thanks!

CC @anakryiko @borkmann

how to provide vmlinux btf information to bpf app on non-btf aware kernel

Hallo libbpf developers

I've just compiled runqslower using linux-5.6
As I understand CORE feature it'd be possible to run it on kernel-5.0 as long as vmlinux btf information could be provided "externally". (IMO pahole could be used to convert dwarf vmlinux to btf?)

Is there a way for libbpf to "consume" such external source?

regards

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.