libbpf | Automated upstream mirror for libbpf stand-alone build | Recommender System library

 by   libbpf C Version: v1.1.0 License: Non-SPDX

kandi X-RAY | libbpf Summary

libbpf is a C library typically used in Artificial Intelligence, Recommender System applications. libbpf has no bugs, it has no vulnerabilities and it has medium support. However libbpf has a Non-SPDX License. You can download it from GitHub.
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 bpf@vger.kernel.org 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. bpf@vger.kernel.org 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. Build
    Support
      Quality
        Security
          License
            Reuse
            Support
              Quality
                Security
                  License
                    Reuse

                      kandi-support Support

                        summary
                        libbpf has a medium active ecosystem.
                        summary
                        It has 1361 star(s) with 319 fork(s). There are 62 watchers for this library.
                        summary
                        There were 2 major release(s) in the last 6 months.
                        summary
                        There are 16 open issues and 195 have been closed. On average issues are closed in 61 days. There are 1 open pull requests and 0 closed requests.
                        summary
                        It has a neutral sentiment in the developer community.
                        summary
                        The latest version of libbpf is v1.1.0
                        libbpf Support
                          Best in #Recommender System
                            Average in #Recommender System
                            libbpf Support
                              Best in #Recommender System
                                Average in #Recommender System

                                  kandi-Quality Quality

                                    summary
                                    libbpf has no bugs reported.
                                    libbpf Quality
                                      Best in #Recommender System
                                        Average in #Recommender System
                                        libbpf Quality
                                          Best in #Recommender System
                                            Average in #Recommender System

                                              kandi-Security Security

                                                summary
                                                libbpf has no vulnerabilities reported, and its dependent libraries have no vulnerabilities reported.
                                                libbpf Security
                                                  Best in #Recommender System
                                                    Average in #Recommender System
                                                    libbpf Security
                                                      Best in #Recommender System
                                                        Average in #Recommender System

                                                          kandi-License License

                                                            summary
                                                            libbpf has a Non-SPDX License.
                                                            summary
                                                            Non-SPDX licenses can be open source with a non SPDX compliant license, or non open source licenses, and you need to review them closely before use.
                                                            libbpf License
                                                              Best in #Recommender System
                                                                Average in #Recommender System
                                                                libbpf License
                                                                  Best in #Recommender System
                                                                    Average in #Recommender System

                                                                      kandi-Reuse Reuse

                                                                        summary
                                                                        libbpf releases are available to install and integrate.
                                                                        summary
                                                                        Installation instructions are not available. Examples and code snippets are available.
                                                                        libbpf Reuse
                                                                          Best in #Recommender System
                                                                            Average in #Recommender System
                                                                            libbpf Reuse
                                                                              Best in #Recommender System
                                                                                Average in #Recommender System
                                                                                  Top functions reviewed by kandi - BETA
                                                                                  kandi's functional review helps you automatically verify the functionalities of the libraries and avoid rework.
                                                                                  Currently covering the most popular Java, JavaScript and Python libraries. See a Sample Here
                                                                                  Get all kandi verified functions for this library.
                                                                                  Get all kandi verified functions for this library.

                                                                                  libbpf Key Features

                                                                                  Automated upstream mirror for libbpf stand-alone build.

                                                                                  libbpf Examples and Code Snippets

                                                                                  No Code Snippets are available at this moment for libbpf.
                                                                                  Community Discussions

                                                                                  Trending Discussions on libbpf

                                                                                  What is the difference between syscalls openat and sys_enter_openat?
                                                                                  chevron right
                                                                                  BPF lib documentation
                                                                                  chevron right
                                                                                  eBPF: 'bpf_map_update()' returns the 'invalid indirect read from stack' error
                                                                                  chevron right
                                                                                  eBPF / XDP map not getting created
                                                                                  chevron right
                                                                                  Unable to initialize BPF_MAP_TYPE_PERCPU_ARRAY
                                                                                  chevron right
                                                                                  printing directory with simple ls and grep command Linux
                                                                                  chevron right
                                                                                  is there a way I can share some ebpf map between ebpf program and userspace program that has value struct using libbpf for keys
                                                                                  chevron right
                                                                                  cannot open shared object file: No such file or directory | including libbpf with userspace program
                                                                                  chevron right
                                                                                  Trying to create map with char array field invalid field error
                                                                                  chevron right
                                                                                  I have a function call in one program and this function is depreciated.Is there any newer version that I can use in my code | perf_buffer__new in ebpf
                                                                                  chevron right

                                                                                  QUESTION

                                                                                  What is the difference between syscalls openat and sys_enter_openat?
                                                                                  Asked 2022-Mar-30 at 09:05

                                                                                  I see for python BCC implementation the syscall __x64_sys_openat is used to attach a kprobe, however in libbpf implementation a kprobe is attached to sys_enter_openat. It seems both capture openat() syscall, I tested it with cat file.txt.

                                                                                  What is the difference between them? And which one is more reliable to use?

                                                                                  ANSWER

                                                                                  Answered 2022-Mar-30 at 09:05

                                                                                  __x64_sys_openat is the name of some function in the Linux kernel, to which BCC attaches a kprobe.

                                                                                  sys_enter_openat is the name of a tracepoint in Linux, meaning that this is a (more or less) stable interface to which you can hook for tracing, including with an eBPF program. You can see the available tracepoints on your system by listing the entries under /sys/kernel/debug/tracing/events/. I think BCC also has a utility called tplist to help with it.

                                                                                  When given the choice, I would recommend hooking at tracepoints if possible, because they tend to be more stable than kernel internals: The parameters for __x64_sys_openat, or the name of that function, could change between different kernel versions for example; or the name would change on an other architecture, et cætera. However, the tracepoint is unlikely to change. Note that the instability of kernel's internals is somewhat mitigated for eBPF with CO-RE.

                                                                                  Then it is not always possible to hook to a tracepoint: You can only use one of the existing tracepoints from the kernel. If you want to hook to another random function where no tracepoint is present (and assuming this function was not inlined at compilation time - check this by looking for it in /proc/kallsyms), then you want to use a kprobe.

                                                                                  Sometimes you also need to pay extra attention to where you hook. For example, for security use cases (i.e. blocking a syscall), syscall tracepoints (or the corresponding kernel functions, obviously) are not always the best hooking points because they might leave you open to TOCTOU attacks. LSM hooks could be a good solution for that use case.

                                                                                  Source https://stackoverflow.com/questions/71668868

                                                                                  QUESTION

                                                                                  BPF lib documentation
                                                                                  Asked 2022-Mar-22 at 23:20

                                                                                  I have created an app with BPF library(https://github.com/libbpf/libbpf). Unfortunately it does not have documentation or at least I have not found it yet. Only thing I have found is this https://libbpf.readthedocs.io/en/latest/api.html, but it does not have everything I need.

                                                                                  I would like to know, what is void *ctx for and what are these ring_buffer_opts in this function.

                                                                                  LIBBPF_API struct ring_buffer *
                                                                                  ring_buffer__new(int map_fd, ring_buffer_sample_fn sample_cb, void *ctx, const struct ring_buffer_opts *opts);
                                                                                  

                                                                                  And here I would like to know what is void *ctx for.

                                                                                  typedef int (*ring_buffer_sample_fn)(void *ctx, void *data, size_t size);
                                                                                  

                                                                                  I prefer link to the documentation, but I am glad for everything.

                                                                                  ANSWER

                                                                                  Answered 2022-Mar-22 at 23:19

                                                                                  You have found the GitHub mirror for the project (the “original” sources are in the Linux kernel repository) and the official API documentation. The latter is generated from the source code, in particular from the comments in src/libbpf.h. It may be that the documentation is not entirely up-to-date, it seems that the description for a few functions is currently missing in the HTML-rendered documentation.

                                                                                  However, not all functions have been documented yet, and the ring buffer API does not have much on this side to help you. So the best I can suggest is to look at the code and at existing examples. There are at least two selftests in the kernel repository which are using ring_buffer__new(): ringbuf.c and ringbuf_multi.c.

                                                                                  The first one (ringbuf.c) calls it like this:

                                                                                      ringbuf = ring_buffer__new(skel->maps.ringbuf.map_fd,
                                                                                                     process_sample, NULL, NULL);
                                                                                  

                                                                                  It passes a pointer to a function called process_sample as the second argument, NULL as ctx for the third argument, and NULL as well for the options.

                                                                                  The callback function, process_sample, is called by ring_buffer__poll() or ring_buffer__consume() on each sample to “process” them according to user's needs. In this example, the callback only works on the data from the sample, printing a line which content depends on whether this is the first or second sample retrieved. The callback needs no “context”: this is why the ctx argument, which is stored by ring_buffer__new() and then passed to the callback function as its first argument each time it runs, is NULL in this case.

                                                                                  For the second example (ringbuf_multi.c), we get a ctx:

                                                                                      ringbuf = ring_buffer__new(bpf_map__fd(skel->maps.ringbuf1),
                                                                                                     process_sample, (void *)(long)1, NULL);
                                                                                      [...]
                                                                                      
                                                                                      err = ring_buffer__add(ringbuf, bpf_map__fd(skel->maps.ringbuf2),
                                                                                                    process_sample, (void *)(long)2);
                                                                                  

                                                                                  The callback function is named process_sample again, but it's a different one (it's defined in the same file as the rest of the example). We also pass a context, 1, and then we add an additional ring buffer, with a different context, 2. If you look at the checks that are performed under that, and at how process_sample is defined, it should give you a good overview of how the ctx works: it is some generic context that you can pass to each individual ring buffer, so that you can process your samples in a different way based on which ring buffer it falls into.

                                                                                  As for the struct ring_buffer_opts * options, always at NULL in the examples, they seem to be unused for now. The code in ring_buffer__new() does not use them.

                                                                                  Source https://stackoverflow.com/questions/71569944

                                                                                  QUESTION

                                                                                  eBPF: 'bpf_map_update()' returns the 'invalid indirect read from stack' error
                                                                                  Asked 2022-Mar-22 at 22:28

                                                                                  I have an eBPF program with the following map definitions:

                                                                                  struct bpf_map_def SEC("maps") servers = {
                                                                                      .type = BPF_MAP_TYPE_HASH,
                                                                                      .key_size = sizeof(struct ip_key),
                                                                                      .value_size = sizeof(struct dest_info),
                                                                                      .max_entries = MAX_SERVERS,
                                                                                  };
                                                                                  
                                                                                  struct bpf_map_def SEC("maps") client_addrs = {
                                                                                      .type = BPF_MAP_TYPE_HASH,
                                                                                      .key_size = sizeof(struct port_key),
                                                                                      .value_size = sizeof(struct client_port_addr),
                                                                                      .max_entries = MAX_CLIENTS,
                                                                                  };
                                                                                  

                                                                                  where the struct definitions are as below:

                                                                                  struct port_key {
                                                                                      __u16 port;
                                                                                      __u16 pad[3];
                                                                                  };
                                                                                  
                                                                                  struct ip_key {
                                                                                      __u32 key;
                                                                                      __u32 pad;
                                                                                  };
                                                                                  
                                                                                  struct dest_info {
                                                                                      __u32 saddr;
                                                                                      __u32 daddr;
                                                                                      __u64 bytes;
                                                                                      __u64 pkts;
                                                                                      __u8 dmac[6];
                                                                                      __u16 pad;
                                                                                  };
                                                                                  
                                                                                  struct client_port_addr {
                                                                                      __u32 client_ip;
                                                                                      __u8 dmac[6];
                                                                                      __u16 pad[3];
                                                                                  };
                                                                                  

                                                                                  The program itself, after the pointer verifications and initial checks, is shown below.

                                                                                  struct port_key key = {0};
                                                                                  struct client_port_addr val;
                                                                                  key.port = udp->source;
                                                                                  val.client_ip = iph->saddr;
                                                                                  memcpy (val.dmac, eth->h_source, 6 * sizeof(__u8));
                                                                                  bpf_map_update_elem(&client_addrs, &key, &val, BPF_ANY);
                                                                                  iph->saddr = IP_ADDRESS(BALANCER);
                                                                                  iph->daddr = dest_tnl->daddr;
                                                                                  memcpy (eth->h_source, eth->h_dest, 6 * sizeof(__u8));
                                                                                  memcpy (eth->h_dest, dest_tnl->dmac, 6 * sizeof(__u8));
                                                                                  

                                                                                  So, the problem is that I use bpf_map_update() in my code, but while using it, I get the invalid indirect read from the stack error as shown below.

                                                                                  libbpf: 
                                                                                  0: (bf) r6 = r1
                                                                                  1: (61) r9 = *(u32 *)(r6 +4)
                                                                                  2: (61) r7 = *(u32 *)(r6 +0)
                                                                                  3: (18) r1 = 0xffffa59ac00b6000
                                                                                  5: (b7) r2 = 24
                                                                                  6: (85) call bpf_trace_printk#6
                                                                                   R1_w=map_value(id=0,off=0,ks=4,vs=50,imm=0) R2_w=inv24 R6_w=ctx(id=0,off=0,imm=0) R7_w=pkt(id=0,off=0,r=0,imm=0) R9_w=pkt_end(id=0,off=0,imm=0) R10=fp0
                                                                                  last_idx 6 first_idx 0
                                                                                  regs=4 stack=0 before 5: (b7) r2 = 24
                                                                                  7: (b7) r8 = 1
                                                                                  8: (bf) r1 = r7
                                                                                  9: (07) r1 += 14
                                                                                  10: (2d) if r1 > r9 goto pc+130
                                                                                   R0_w=inv(id=0) R1_w=pkt(id=0,off=14,r=14,imm=0) R6_w=ctx(id=0,off=0,imm=0) R7_w=pkt(id=0,off=0,r=14,imm=0) R8_w=inv1 R9_w=pkt_end(id=0,off=0,imm=0) R10=fp0
                                                                                  11: (71) r1 = *(u8 *)(r7 +12)
                                                                                  12: (71) r2 = *(u8 *)(r7 +13)
                                                                                  13: (67) r2 <<= 8
                                                                                  14: (4f) r2 |= r1
                                                                                  15: (b7) r8 = 2
                                                                                  16: (55) if r2 != 0x8 goto pc+124
                                                                                   R0=inv(id=0) R1=inv(id=0,umax_value=255,var_off=(0x0; 0xff)) R2=inv8 R6=ctx(id=0,off=0,imm=0) R7=pkt(id=0,off=0,r=14,imm=0) R8=inv2 R9=pkt_end(id=0,off=0,imm=0) R10=fp0
                                                                                  17: (61) r7 = *(u32 *)(r6 +4)
                                                                                  18: (61) r9 = *(u32 *)(r6 +0)
                                                                                  19: (bf) r6 = r9
                                                                                  20: (07) r6 += 14
                                                                                  21: (b7) r8 = 1
                                                                                  22: (2d) if r6 > r7 goto pc+118
                                                                                   R0=inv(id=0) R1=inv(id=0,umax_value=255,var_off=(0x0; 0xff)) R2=inv8 R6_w=pkt(id=0,off=14,r=14,imm=0) R7_w=pkt_end(id=0,off=0,imm=0) R8_w=inv1 R9_w=pkt(id=0,off=0,r=14,imm=0) R10=fp0
                                                                                  23: (bf) r1 = r9
                                                                                  24: (07) r1 += 34
                                                                                  25: (b7) r8 = 1
                                                                                  26: (2d) if r1 > r7 goto pc+114
                                                                                   R0=inv(id=0) R1=pkt(id=0,off=34,r=34,imm=0) R2=inv8 R6=pkt(id=0,off=14,r=34,imm=0) R7=pkt_end(id=0,off=0,imm=0) R8=inv1 R9=pkt(id=0,off=0,r=34,imm=0) R10=fp0
                                                                                  27: (71) r1 = *(u8 *)(r6 +0)
                                                                                  28: (57) r1 &= 15
                                                                                  29: (b7) r8 = 1
                                                                                  30: (55) if r1 != 0x5 goto pc+110
                                                                                   R0=inv(id=0) R1_w=inv5 R2=inv8 R6=pkt(id=0,off=14,r=34,imm=0) R7=pkt_end(id=0,off=0,imm=0) R8_w=inv1 R9=pkt(id=0,off=0,r=34,imm=0) R10=fp0
                                                                                  31: (61) r3 = *(u32 *)(r9 +26)
                                                                                  32: (18) r1 = 0xffffa59ac00b6018
                                                                                  34: (b7) r2 = 26
                                                                                  35: (85) call bpf_trace_printk#6
                                                                                   R0=inv(id=0) R1_w=map_value(id=0,off=24,ks=4,vs=50,imm=0) R2_w=inv26 R3_w=inv(id=0,umax_value=4294967295,var_off=(0x0; 0xffffffff)) R6=pkt(id=0,off=14,r=34,imm=0) R7=pkt_end(id=0,off=0,imm=0) R8_w=inv1 R9=pkt(id=0,off=0,r=34,imm=0) R10=fp0
                                                                                  last_idx 35 first_idx 26
                                                                                  regs=4 stack=0 before 34: (b7) r2 = 26
                                                                                  36: (69) r1 = *(u16 *)(r9 +20)
                                                                                  37: (57) r1 &= 65343
                                                                                  38: (b7) r8 = 1
                                                                                  39: (55) if r1 != 0x0 goto pc+101
                                                                                   R0=inv(id=0) R1_w=inv0 R6=pkt(id=0,off=14,r=34,imm=0) R7=pkt_end(id=0,off=0,imm=0) R8_w=inv1 R9=pkt(id=0,off=0,r=34,imm=0) R10=fp0
                                                                                  40: (71) r1 = *(u8 *)(r9 +23)
                                                                                  41: (b7) r8 = 2
                                                                                  42: (55) if r1 != 0x11 goto pc+98
                                                                                   R0=inv(id=0) R1_w=inv17 R6=pkt(id=0,off=14,r=34,imm=0) R7=pkt_end(id=0,off=0,imm=0) R8_w=inv2 R9=pkt(id=0,off=0,r=34,imm=0) R10=fp0
                                                                                  43: (bf) r1 = r9
                                                                                  44: (07) r1 += 42
                                                                                  45: (b7) r8 = 1
                                                                                  46: (2d) if r1 > r7 goto pc+94
                                                                                   R0=inv(id=0) R1=pkt(id=0,off=42,r=42,imm=0) R6=pkt(id=0,off=14,r=42,imm=0) R7=pkt_end(id=0,off=0,imm=0) R8=inv1 R9=pkt(id=0,off=0,r=42,imm=0) R10=fp0
                                                                                  47: (b7) r8 = 0
                                                                                  48: (7b) *(u64 *)(r10 -8) = r8
                                                                                  last_idx 48 first_idx 46
                                                                                  regs=100 stack=0 before 47: (b7) r8 = 0
                                                                                  49: (bf) r2 = r10
                                                                                  50: (07) r2 += -8
                                                                                  51: (18) r1 = 0xffff9a7bed1bc000
                                                                                  53: (85) call bpf_map_lookup_elem#1
                                                                                  54: (bf) r7 = r0
                                                                                  55: (15) if r7 == 0x0 goto pc+85
                                                                                   R0=map_value(id=0,off=0,ks=8,vs=32,imm=0) R6=pkt(id=0,off=14,r=42,imm=0) R7=map_value(id=0,off=0,ks=8,vs=32,imm=0) R8=invP0 R9=pkt(id=0,off=0,r=42,imm=0) R10=fp0 fp-8=mmmmmmmm
                                                                                  56: (b7) r8 = 0
                                                                                  57: (7b) *(u64 *)(r10 -16) = r8
                                                                                  last_idx 57 first_idx 55
                                                                                  regs=100 stack=0 before 56: (b7) r8 = 0
                                                                                  58: (69) r1 = *(u16 *)(r9 +34)
                                                                                  59: (6b) *(u16 *)(r10 -16) = r1
                                                                                  60: (61) r1 = *(u32 *)(r9 +26)
                                                                                  61: (63) *(u32 *)(r10 -32) = r1
                                                                                  62: (71) r1 = *(u8 *)(r9 +11)
                                                                                  63: (73) *(u8 *)(r10 -23) = r1
                                                                                  64: (71) r1 = *(u8 *)(r9 +10)
                                                                                  65: (73) *(u8 *)(r10 -24) = r1
                                                                                  66: (71) r1 = *(u8 *)(r9 +7)
                                                                                  67: (67) r1 <<= 8
                                                                                  68: (71) r2 = *(u8 *)(r9 +6)
                                                                                  69: (4f) r1 |= r2
                                                                                  70: (71) r2 = *(u8 *)(r9 +9)
                                                                                  71: (67) r2 <<= 8
                                                                                  72: (71) r3 = *(u8 *)(r9 +8)
                                                                                  73: (4f) r2 |= r3
                                                                                  74: (67) r2 <<= 16
                                                                                  75: (4f) r2 |= r1
                                                                                  76: (63) *(u32 *)(r10 -28) = r2
                                                                                  77: (bf) r2 = r10
                                                                                  78: (07) r2 += -16
                                                                                  79: (bf) r3 = r10
                                                                                  80: (07) r3 += -32
                                                                                  81: (18) r1 = 0xffff9a7bed1bf400
                                                                                  83: (b7) r4 = 0
                                                                                  84: (85) call bpf_map_update_elem#2
                                                                                  invalid indirect read from stack R3 off -32+10 size 16
                                                                                  processed 81 insns (limit 1000000) max_states_per_insn 0 total_states 5 peak_states 5 mark_read 2
                                                                                  
                                                                                  libbpf: -- END LOG --
                                                                                  libbpf: failed to load program 'loadbal'
                                                                                  

                                                                                  All of the defined structs for keys and values are padded to their next multiple of 8 bytes. Since I could not find any useful and descriptive explanation on my issue, explanations of this topic and maybe even a bit of detail are much appreciated.

                                                                                  Please let me know if you need more information.

                                                                                  ANSWER

                                                                                  Answered 2022-Mar-22 at 22:28

                                                                                  The verifier complains because your code is trying to read uninitialised data from the stack, in particular in your variable val.

                                                                                  If we look at your code:

                                                                                  struct client_port_addr {
                                                                                      __u32 client_ip;
                                                                                      __u8 dmac[6];
                                                                                      __u16 pad[3];
                                                                                  };
                                                                                  
                                                                                  struct client_port_addr val;
                                                                                  [...]
                                                                                  val.client_ip = iph->saddr;                                  // val.client_ip
                                                                                  memcpy (val.dmac, eth->h_source, 6 * sizeof(__u8));          // val.dmac
                                                                                                                                               // val.pad where??
                                                                                  bpf_map_update_elem(&client_addrs, &key, &val, BPF_ANY);
                                                                                  

                                                                                  You initialised val.client_ip, and val.dmac, but val.pad is never initialised. When you pass val to bpf_map_update_elem(), the eBPF verifier realises that the helper function might read this variable which contains uninitialised memory from kernel space. This is a security risk, therefore, the verifier rejects the program.

                                                                                  To fix the issue, make sure you initialise the memory before using it. You have at least three ways to do so:

                                                                                  • You could initialise val when declaring it, like for your key:
                                                                                  struct client_port_addr val = {0};
                                                                                  
                                                                                  This should work in your case, but is not generally recommended, because this will set all fields to 0 but if your struct contains padding that was not explicitely added, it may remain uninitialised.
                                                                                • In your case, you could fill val.pad with zeroes with memcpy(). Same as the first option, this won't help if the compiler pads your struct.
                                                                                • The safest option would be to memset() the struct after declaring it:
                                                                                • struct client_port_addr val;
                                                                                  
                                                                                  memset(&val, 0, sizeof(val));
                                                                                  
                                                                                  Then you can fill the relevant fields of the struct, and pass it to the map update helper.

                                                                                  Source https://stackoverflow.com/questions/71529801

                                                                                  QUESTION

                                                                                  eBPF / XDP map not getting created
                                                                                  Asked 2022-Mar-19 at 23:24

                                                                                  I have an implementation in BPF for XDP, wherein I specify five maps to be created as follows:

                                                                                      struct bpf_map_def SEC("maps") servers = {
                                                                                          .type = BPF_MAP_TYPE_HASH,
                                                                                          .key_size = sizeof(struct ip_key),
                                                                                          .value_size = sizeof(struct dest_info),
                                                                                          .max_entries = MAX_SERVERS,
                                                                                      };
                                                                                      
                                                                                      struct bpf_map_def SEC("maps") server_ips = {
                                                                                          .type = BPF_MAP_TYPE_HASH,
                                                                                          .key_size = sizeof(struct ip_key),
                                                                                          .value_size = sizeof(struct server_ip_key),
                                                                                          .max_entries = MAX_SERVERS,
                                                                                      };
                                                                                      
                                                                                      struct bpf_map_def SEC("maps") client_addrs = {
                                                                                          .type = BPF_MAP_TYPE_HASH,
                                                                                          .key_size = sizeof(struct port_key),
                                                                                          .value_size = sizeof(struct client_port_addr),
                                                                                          .max_entries = MAX_CLIENTS,
                                                                                      };
                                                                                      
                                                                                      struct bpf_map_def SEC("maps") stoc_port_maps = {
                                                                                          .type = BPF_MAP_TYPE_HASH,
                                                                                          .key_size = sizeof(struct port_key),
                                                                                          .value_size = sizeof(struct port_map),
                                                                                          .max_entries = MAX_FLOWS,
                                                                                      };
                                                                                      
                                                                                      struct bpf_map_def SEC("maps") ctos_port_maps = {
                                                                                          .type = BPF_MAP_TYPE_HASH,
                                                                                          .key_size = sizeof(struct port_key),
                                                                                          .value_size = sizeof(struct port_map),
                                                                                          .max_entries = MAX_FLOWS,
                                                                                      };
                                                                                  

                                                                                  However, no matter what I do, the servers map is not getting created. When I run bpftool map show, I only get such output as the following:

                                                                                  root@balancer:/xdp# bpftool map list  
                                                                                  68: hash  name client_addrs  flags 0x0
                                                                                          key 8B  value 16B  max_entries 4096  memlock 98304B
                                                                                  69: hash  name ctos_port_maps  flags 0x0
                                                                                          key 8B  value 20B  max_entries 4096  memlock 131072B
                                                                                  70: hash  name server_ips  flags 0x0
                                                                                          key 8B  value 8B  max_entries 512  memlock 8192B
                                                                                  73: hash  name stoc_port_maps  flags 0x0
                                                                                          key 8B  value 20B  max_entries 4096  memlock 131072B
                                                                                  74: array  name xdp_lb_k.rodata  flags 0x480
                                                                                          key 4B  value 50B  max_entries 1  memlock 4096B
                                                                                          frozen
                                                                                  root@balancer:/xdp#
                                                                                  

                                                                                  It is notable that each of the key or value structs have been padded to the closest multiple of eight bytes, and there are no compile or verifier errors. I am also running the program on docker containers. So far, I have tried moving the servers map definition around in my code, commenting out the other map definitions leaving only the servers definition active, changing the name to other combinations, and a few other minor changes but nothing has worked so far.

                                                                                  Please let me know if you would need any other portion of my code or information for a better analysis of the situation.

                                                                                  Appendix 1: I am compiling the object file using this Makefile rule:

                                                                                  xdp_lb_kern.o: xdp_lb_kern.c 
                                                                                      clang -S \
                                                                                          -target bpf \
                                                                                          -D __BPF_TRACING__ \
                                                                                          -I../../libbpf/src \
                                                                                          -I../../custom-headers \
                                                                                          -Wall \
                                                                                          -Wno-unused-value \
                                                                                          -Wno-pointer-sign \
                                                                                          -Wno-compare-distinct-pointer-types \
                                                                                          -O2 -emit-llvm -c -o ${@:.o=.ll} $<
                                                                                      llc -march=bpf -filetype=obj -o $@ ${@:.o=.ll}
                                                                                  

                                                                                  Then, in the container's environment, I load the program using this rule:

                                                                                  load_balancer:
                                                                                      bpftool net detach xdpgeneric dev eth0
                                                                                      rm -f /sys/fs/bpf/xdp_lb
                                                                                      bpftool prog load xdp_lb_kern.o /sys/fs/bpf/xdp_lb
                                                                                      bpftool net attach xdpgeneric pinned /sys/fs/bpf/xdp_lb dev eth0
                                                                                  

                                                                                  The compilation process generates a .o and a .ll output file. The beginning lines of the .ll output file, where the map definitions are visible, are shown below:

                                                                                  ; ModuleID = 'xdp_lb_kern.c'
                                                                                  source_filename = "xdp_lb_kern.c"
                                                                                  target datalayout = "e-m:e-p:64:64-i64:64-n32:64-S128"
                                                                                  target triple = "bpf"
                                                                                  
                                                                                  %struct.bpf_map_def = type { i32, i32, i32, i32, i32 }
                                                                                  %struct.xdp_md = type { i32, i32, i32, i32, i32 }
                                                                                  %struct.ip_key = type { i32, i32 }
                                                                                  %struct.port_key = type { i16, [3 x i16] }
                                                                                  %struct.ethhdr = type { [6 x i8], [6 x i8], i16 }
                                                                                  %struct.iphdr = type { i8, i8, i16, i16, i16, i8, i8, i16, i32, i32 }
                                                                                  
                                                                                  @servers = dso_local global %struct.bpf_map_def { i32 1, i32 8, i32 32, i32 512, i32 0 }, section "maps", align 4
                                                                                  @server_ips = dso_local global %struct.bpf_map_def { i32 1, i32 8, i32 8, i32 512, i32 0 }, section "maps", align 4
                                                                                  @client_addrs = dso_local global %struct.bpf_map_def { i32 1, i32 8, i32 16, i32 4096, i32 0 }, section "maps", align 4
                                                                                  @stoc_port_maps = dso_local global %struct.bpf_map_def { i32 1, i32 8, i32 20, i32 4096, i32 0 }, section "maps", align 4
                                                                                  @ctos_port_maps = dso_local global %struct.bpf_map_def { i32 1, i32 8, i32 20, i32 4096, i32 0 }, section "maps", align 4
                                                                                  @loadbal.____fmt = internal constant [24 x i8] c"balancer got something!\00", align 1
                                                                                  @_license = dso_local global [4 x i8] c"GPL\00", section "license", align 1
                                                                                  @process_packet.____fmt = internal constant [26 x i8] c"it's an ip packet from %x\00", align 1
                                                                                  @llvm.used = appending global [7 x i8*] [i8* getelementptr inbounds ([4 x i8], [4 x i8]* @_license, i32 0, i32 0), i8* bitcast (%struct.bpf_map_def* @client_addrs to i8*), i8* bitcast (%struct.bpf_map_def* @ctos_port_maps to i8*), i8* bitcast (i32 (%struct.xdp_md*)* @loadbal to i8*), i8* bitcast (%struct.bpf_map_def* @server_ips to i8*), i8* bitcast (%struct.bpf_map_def* @servers to i8*), i8* bitcast (%struct.bpf_map_def* @stoc_port_maps to i8*)], section "llvm.metadata"
                                                                                  
                                                                                  ; Function Attrs: nounwind
                                                                                  define dso_local i32 @loadbal(%struct.xdp_md* nocapture readonly %0) #0 section "xdp" {
                                                                                    %2 = alloca %struct.ip_key, align 4
                                                                                    %3 = alloca %struct.port_key, align 2
                                                                                    %4 = alloca %struct.port_key, align 2
                                                                                    %5 = getelementptr inbounds %struct.xdp_md, %struct.xdp_md* %0, i64 0, i32 1
                                                                                    %6 = load i32, i32* %5, align 4, !tbaa !2
                                                                                    %7 = zext i32 %6 to i64
                                                                                    %8 = inttoptr i64 %7 to i8*
                                                                                    %9 = getelementptr inbounds %struct.xdp_md, %struct.xdp_md* %0, i64 0, i32 0
                                                                                    %10 = load i32, i32* %9, align 4, !tbaa !7
                                                                                  

                                                                                  ANSWER

                                                                                  Answered 2022-Mar-19 at 23:24

                                                                                  As per the discussion in the comments, the map is not created because it is not actually used in your eBPF code (not provided in the question).

                                                                                  As you realised yourself, the branch in your code that was calling the map was in fact unreachable. Based on that, it's likely that clang compiled out this portion of code, and that the map is not used in the resulting eBPF bytecode. When preparing to load your program, bpftool (libbpf) looks at what maps are necessary, and only creates the ones that are needed for your program. It may skip maps that are defined in the ELF file if no program uses them.

                                                                                  One hint here is that, if the program was effectively using the map, it couldn't load successfully if the map was missing: given that your program loads, the map would necessarily be present if it was needed. Note that bpftool prog show will show you the ids of the maps used by a program.

                                                                                  Source https://stackoverflow.com/questions/71510575

                                                                                  QUESTION

                                                                                  Unable to initialize BPF_MAP_TYPE_PERCPU_ARRAY
                                                                                  Asked 2022-Mar-17 at 00:32

                                                                                  Here's how I'm trying to initialize a BPF_MAP_TYPE_PERCPU_ARRAY of structs to a default value. The array contains counters the user space program will read.

                                                                                  #include 
                                                                                  #include 
                                                                                  
                                                                                  struct xdp_stats_t {
                                                                                      __u64 total_packets;
                                                                                  };
                                                                                  
                                                                                  struct xdp_stats_t xdp_stats = {0};
                                                                                  
                                                                                  struct {
                                                                                      __uint(type, BPF_MAP_TYPE_PERCPU_ARRAY);
                                                                                      __uint(key_size, sizeof(__u32));
                                                                                      __uint(value_size, sizeof(struct xdp_stats_t));
                                                                                      __uint(max_entries, 1);
                                                                                      __array(values, struct xdp_stats_t);
                                                                                  } counter_table SEC(".maps") = {
                                                                                      .values = {
                                                                                          [0] = &xdp_stats
                                                                                      }
                                                                                  };
                                                                                  
                                                                                  SEC("xdp")
                                                                                  int main_prog(struct xdp_md *ctx) {
                                                                                      return XDP_PASS;
                                                                                  }
                                                                                  
                                                                                  char _license[] SEC("license") = "GPL";
                                                                                  

                                                                                  But I get this error when I try to load the BPF program:

                                                                                  libbpf: map 'counter_table': should be map-in-map.
                                                                                  

                                                                                  ANSWER

                                                                                  Answered 2022-Mar-16 at 19:52

                                                                                  This specific part is triggering this error:

                                                                                      .values = {
                                                                                          [0] = &xdp_stats
                                                                                      }
                                                                                  

                                                                                  In libbpf, when loading a BPF structure with a .values entry, it checks that the type is either a BPF_MAP_TYPE_ARRAY_OF_MAPS, a BPF_MAP_TYPE_HASH_OF_MAPS, or BPF_MAP_TYPE_PROG_ARRAY. If not, it won't let you use .values. The check is defined in libbpf here.

                                                                                  I can't find any kernel documentation that says this directly, but I believe those arrays will be zero-initialized, so there's no need to initialize them. Here's the most on-point documentation I can find:

                                                                                  BPF_MAP_TYPE_ARRAY
                                                                                                Array maps have the following characteristics:
                                                                                  
                                                                                                [...]
                                                                                  
                                                                                                *  All array elements pre-allocated and zero initialized
                                                                                                   at init time
                                                                                  

                                                                                  (Source.)

                                                                                  I can't find any documentation saying the same thing about BPF_MAP_TYPE_PERCPU_ARRAY. I assume it's similar.

                                                                                  Source https://stackoverflow.com/questions/71502790

                                                                                  QUESTION

                                                                                  printing directory with simple ls and grep command Linux
                                                                                  Asked 2022-Jan-31 at 08:11

                                                                                  So I have this command ls -al -R | grep libbpf.h and it just act dump print

                                                                                   -rw-r--r-- 1 root root   53107 جنوری  27 12:05 libbpf.h
                                                                                  

                                                                                  I also need the exact subdirectories that contain this file is there a way I can use the above command with some option for grep or ls so it also prints some thining like

                                                                                   -rw-r--r-- 1 root root ./libbpf/src/include/libbpf.h  53107 جنوری  27 12:05 libbpf.h
                                                                                  

                                                                                  so I only knows the the libbpf.h does exists in somewhere from root directory recursively searching just give me the path, does any one knows this

                                                                                  ANSWER

                                                                                  Answered 2022-Jan-31 at 08:11

                                                                                  you can use find command

                                                                                  find "$(pwd -P)" -type f -name "libbpf.h" -ls
                                                                                  

                                                                                  if you want only paths

                                                                                  find "$(pwd -P)" -type f -name "libbpf.h"
                                                                                  or
                                                                                  find . -type f -name "libbpf.h" -exec realpath {} \;
                                                                                  

                                                                                  Source https://stackoverflow.com/questions/70922399

                                                                                  QUESTION

                                                                                  is there a way I can share some ebpf map between ebpf program and userspace program that has value struct using libbpf for keys
                                                                                  Asked 2022-Jan-16 at 11:11

                                                                                  So I created a map of type BPF_MAP_TYPE_ARRAY.

                                                                                  struct share_me
                                                                                  {
                                                                                  
                                                                                      struct iphdr dest_ip;
                                                                                  };
                                                                                  
                                                                                  struct bpf_map_def SEC("maps") ip_map = {
                                                                                      .type = BPF_MAP_TYPE_ARRAY,
                                                                                      .key_size = sizeof(int),
                                                                                      .value_size = sizeof(struct share_me),
                                                                                      .max_entries = 64,  /* Assume netdev has no more than 64 queues */
                                                                                  };
                                                                                  

                                                                                  so ip_map is my map and its defined and SEC elf sections used to create the map in above defination

                                                                                  In my ebpf program function I am doing

                                                                                  SEC("xdp_sock")
                                                                                  int xdp_sock_prog(struct xdp_md *ctx)
                                                                                  {
                                                                                      int index = ctx->rx_queue_index;
                                                                                      __u32 *pkt_count;
                                                                                  
                                                                                      void *data = (void *)(long)ctx->data;
                                                                                      void *data_end = (void *)(long)ctx->data_end;
                                                                                      struct ethhdr *eth = data;  
                                                                                      struct share_me me; 
                                                                                  
                                                                                      if ((void *)eth + sizeof(*eth) <= data_end)
                                                                                      {
                                                                                  
                                                                                          struct iphdr *ip = data + sizeof(*eth);
                                                                                          //me.dest_ip=ip;    
                                                                                          memcpy(&me.dest_ip,ip,sizeof(struct iphdr));    
                                                                                          bpf_map_lookup_elem(&ip_map, &index);
                                                                                          bpf_map_update_elem(&ip_map,&index,&me,0);  
                                                                                  

                                                                                  so with I am updating currrent value of ip_map key with my struct object

                                                                                  And this is what I am doing in usespace program

                                                                                          bpf_obj = load_bpf_and_xdp_attach(&cfg);
                                                                                          if (!bpf_obj) {
                                                                                              /* Error handling done in load_bpf_and_xdp_attach() */
                                                                                              exit(EXIT_FAILURE);
                                                                                          }
                                                                                  
                                                                                          /* We also need to load the xsks_map */
                                                                                          
                                                                                          map1 = bpf_object__find_map_by_name(bpf_obj, "ip_map");
                                                                                          xsks_map_fd = bpf_map__fd(map);
                                                                                          map_fd = bpf_map__fd(map1);
                                                                                          if(map_fd<0)
                                                                                          {
                                                                                              printf("map_fd <0\n");
                                                                                              exit(0);
                                                                                          }
                                                                                          
                                                                                          if (xsks_map_fd < 0) {
                                                                                              fprintf(stderr, "ERROR: no xsks map found: %s\n",
                                                                                                  strerror(xsks_map_fd));
                                                                                              exit(EXIT_FAILURE);
                                                                                          }
                                                                                  

                                                                                  This is load_bpf_and_xdp_attach function just a wrapper around bpf/libbpf so calls load_bpf_object_file etc,

                                                                                  struct bpf_object *load_bpf_and_xdp_attach(struct config *cfg)
                                                                                  {
                                                                                      struct bpf_program *bpf_prog;
                                                                                      struct bpf_object *bpf_obj;
                                                                                      int offload_ifindex = 0;
                                                                                      int prog_fd = -1;
                                                                                      int err;
                                                                                  
                                                                                      /* If flags indicate hardware offload, supply ifindex */
                                                                                      if (cfg->xdp_flags & XDP_FLAGS_HW_MODE)
                                                                                          offload_ifindex = cfg->ifindex;
                                                                                  
                                                                                      /* Load the BPF-ELF object file and get back libbpf bpf_object */
                                                                                      if (cfg->reuse_maps)
                                                                                          bpf_obj = load_bpf_object_file_reuse_maps(cfg->filename,
                                                                                                                offload_ifindex,
                                                                                                                cfg->pin_dir);
                                                                                      else
                                                                                          bpf_obj = load_bpf_object_file(cfg->filename, offload_ifindex);
                                                                                      if (!bpf_obj) {
                                                                                          fprintf(stderr, "ERR: loading file: %s\n", cfg->filename);
                                                                                          exit(EXIT_FAIL_BPF);
                                                                                      }
                                                                                      /* At this point: All XDP/BPF programs from the cfg->filename have been
                                                                                       * loaded into the kernel, and evaluated by the verifier. Only one of
                                                                                       * these gets attached to XDP hook, the others will get freed once this
                                                                                       * process exit.
                                                                                       */
                                                                                  
                                                                                      if (cfg->progsec[0])
                                                                                          /* Find a matching BPF prog section name */
                                                                                          bpf_prog = bpf_object__find_program_by_title(bpf_obj, cfg->progsec);
                                                                                      else
                                                                                          /* Find the first program */
                                                                                          bpf_prog = bpf_program__next(NULL, bpf_obj);
                                                                                  
                                                                                      if (!bpf_prog) {
                                                                                          fprintf(stderr, "ERR: couldn't find a program in ELF section '%s'\n", cfg->progsec);
                                                                                          exit(EXIT_FAIL_BPF);
                                                                                      }
                                                                                  
                                                                                      strncpy(cfg->progsec, bpf_program__title(bpf_prog, false), sizeof(cfg->progsec));
                                                                                  
                                                                                      prog_fd = bpf_program__fd(bpf_prog);
                                                                                      if (prog_fd <= 0) {
                                                                                          fprintf(stderr, "ERR: bpf_program__fd failed\n");
                                                                                          exit(EXIT_FAIL_BPF);
                                                                                      }
                                                                                  
                                                                                      /* At this point: BPF-progs are (only) loaded by the kernel, and prog_fd
                                                                                       * is our select file-descriptor handle. Next step is attaching this FD
                                                                                       * to a kernel hook point, in this case XDP net_device link-level hook.
                                                                                       */
                                                                                      err = xdp_link_attach(cfg->ifindex, cfg->xdp_flags, prog_fd);
                                                                                      if (err)
                                                                                          exit(err);
                                                                                  
                                                                                      return bpf_obj;
                                                                                  }
                                                                                  

                                                                                  But I am getting error that

                                                                                  libbpf: load bpf program failed: Permission denied
                                                                                  libbpf: -- BEGIN DUMP LOG ---
                                                                                  libbpf: 
                                                                                  ; int index = ctx->rx_queue_index;
                                                                                  0: (61) r2 = *(u32 *)(r1 +16)
                                                                                  ; int index = ctx->rx_queue_index;
                                                                                  1: (63) *(u32 *)(r10 -4) = r2
                                                                                  ; void *data_end = (void *)(long)ctx->data_end;
                                                                                  2: (61) r2 = *(u32 *)(r1 +4)
                                                                                  ; void *data = (void *)(long)ctx->data;
                                                                                  3: (61) r1 = *(u32 *)(r1 +0)
                                                                                  ; if ((void *)eth + sizeof(*eth) <= data_end)
                                                                                  4: (07) r1 += 14
                                                                                  ; if ((void *)eth + sizeof(*eth) <= data_end)
                                                                                  5: (2d) if r1 > r2 goto pc+25
                                                                                   R1_w=pkt(id=0,off=14,r=14,imm=0) R2_w=pkt_end(id=0,off=0,imm=0) R10=fp0 fp-8=mmmm????
                                                                                  ; memcpy(&me.dest_ip,ip,sizeof(struct iphdr));  
                                                                                  6: (61) r2 = *(u32 *)(r1 +16)
                                                                                  invalid access to packet, off=30 size=4, R1(id=0,off=30,r=14)
                                                                                  R1 offset is outside of the packet
                                                                                  processed 7 insns (limit 1000000) max_states_per_insn 0 total_states 0 peak_states 0 mark_read 0
                                                                                  
                                                                                  libbpf: -- END LOG --
                                                                                  libbpf: failed to load program 'xdp_sock'
                                                                                  libbpf: failed to load object 'af_xdp_kern.o'
                                                                                  ERR: loading BPF-OBJ file(af_xdp_kern.o) (-22): Invalid argument
                                                                                  ERR: loading file: af_xdp_kern.o
                                                                                  

                                                                                  so I am getting invalid access to packet, off=30 size=4, R1(id=0,off=30,r=14) R1 offset is outside of the packet when load my ebpf program I am kind of sure that the error caused because of I am using struct value as map of type BPF_MAP_TYPE_ARRY value

                                                                                  So I like to know is there any other MAP type there if I am using libbpf that allows struct as map key's value

                                                                                  ANSWER

                                                                                  Answered 2022-Jan-16 at 11:11

                                                                                  TL;DR. The issue is that you're making an out-of-bound access to the packet from the verifier's point of view. You need to check the packet is long enough to actually contain the IP header first.

                                                                                  Reading the verifier error message.

                                                                                  ; memcpy(&me.dest_ip,ip,sizeof(struct iphdr));  
                                                                                  6: (61) r2 = *(u32 *)(r1 +16)
                                                                                  invalid access to packet, off=30 size=4, R1(id=0,off=30,r=14)
                                                                                  R1 offset is outside of the packet
                                                                                  

                                                                                  The verifier errors on instruction 6, which corresponds to the memcpy statement. It states that you are making an invalid access to the packet, with the offset hold in R1 being outside the known bounds of the packet.

                                                                                  You checked that the packet is at least long enough to hold the Ethernet header, but you never checked that it's long enough to hold the IP header. So the verifier sees you trying to access bytes beyond the Ethernet header (up to offset 30) and errors.

                                                                                  Updating the packet bounds check.

                                                                                  If you already know from the start you'll need to read both the Ethernet and IP headers, you can update your check from:

                                                                                  if ((void *)eth + sizeof(*eth) <= data_end)
                                                                                  

                                                                                  to:

                                                                                  if ((void *)eth + sizeof(*eth) + sizeof(struct iphdr) <= data_end)
                                                                                  

                                                                                  Source https://stackoverflow.com/questions/70721661

                                                                                  QUESTION

                                                                                  cannot open shared object file: No such file or directory | including libbpf with userspace program
                                                                                  Asked 2022-Jan-13 at 14:22

                                                                                  So in my userspace program I am calling some functions like bpf_object__open_file which are part of libbpf library installed with PKG_CONFIG_PATH=/build/root/lib64/pkgconfig DESTDIR=/build/root make install

                                                                                  So when I compile the it compiles just fine, no error with this command

                                                                                    clang -L /build/root/usr/lib64/ -I /usr/include/ -Wall -o user u.c -lbpf
                                                                                  

                                                                                  so these files exists in my /build/root/usr/lib64 directory

                                                                                      libbpf.a  libbpf.so  libbpf.so.0  libbpf.so.0.7.0  pkgconfig
                                                                                  

                                                                                  But when I run the program like

                                                                                   sudo ./user
                                                                                  

                                                                                  It throws message that

                                                                                   ./user: error while loading shared libraries: libbpf.so.0: cannot open shared object file: No such file or directory
                                                                                  

                                                                                  So basically I am creating shared library, giving the path but why running the program not able to find my libbpf.so.0 shared library

                                                                                  can anyone tell why is that the case I am getting message can't find library

                                                                                  As Qeole mentioned in comment

                                                                                  So I did this

                                                                                  root@/dir/# ldd ./user

                                                                                  and it gives me this output without any location where did it tried to find path directory

                                                                                  linux-vdso.so.1 (0x00007ffcd77e7000)
                                                                                  libbpf.so.0 => not found
                                                                                  libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f9b3943c000)
                                                                                  /lib64/ld-linux-x86-64.so.2 (0x00007f9b39642000)
                                                                                  

                                                                                  ANSWER

                                                                                  Answered 2022-Jan-13 at 14:22

                                                                                  You should add the libbpf library directory to your LD_LIBRARY_PATH variable.

                                                                                  $ LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/build/root/usr/lib64
                                                                                  $ export LD_LIBRARY_PATH
                                                                                  

                                                                                  Then go ahead an run the program. Note that if you run it with sudo, you may also need to set root's LD_LIBRARY_PATH

                                                                                  $ sudo su
                                                                                  # LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/build/root/usr/lib64
                                                                                  # export LD_LIBRARY_PATH
                                                                                  # ./user
                                                                                  

                                                                                  You can verify that libbfp was found with the same ldd command.

                                                                                  Source https://stackoverflow.com/questions/70696552

                                                                                  QUESTION

                                                                                  Trying to create map with char array field invalid field error
                                                                                  Asked 2022-Jan-12 at 10:28

                                                                                  I like to know how to create ebpf map with char array value

                                                                                  I tried like this

                                                                                  struct {
                                                                                      __uint(type, BPF_MAP_TYPE_PERF_EVENT_ARRAY);
                                                                                      __uint(key_size, sizeof(int));
                                                                                      __uint(value_size, sizeof(char)*10);
                                                                                      __uint(max_entries, 2);
                                                                                  } my_map SEC(".maps");
                                                                                  

                                                                                  and this is full code for the ebpf program

                                                                                  #include 
                                                                                  #include 
                                                                                  #include 
                                                                                  #include 
                                                                                  
                                                                                  struct {
                                                                                      __uint(type, BPF_MAP_TYPE_PERF_EVENT_ARRAY);
                                                                                      __uint(key_size, sizeof(int));
                                                                                      __uint(value_size, sizeof(char)*10);
                                                                                      __uint(max_entries, 2);
                                                                                  } my_map SEC(".maps");
                                                                                  
                                                                                  SEC("kprobe/__x64_sys_write")
                                                                                  int bpf_prog1(struct pt_regs *ctx)
                                                                                  {
                                                                                      struct S {
                                                                                          int pid;
                                                                                          char cookie[10];
                                                                                      } data;
                                                                                  
                                                                                      data.pid = bpf_get_current_pid_tgid();
                                                                                  //      data.cookie = 0x123;
                                                                                      memcpy(data.cookie,"msg fwd",sizeof("msg fwd"));
                                                                                  
                                                                                      bpf_perf_event_output(ctx, &my_map, 0, &data, sizeof(data));
                                                                                  
                                                                                      return 0;
                                                                                  
                                                                                  
                                                                                  }
                                                                                  
                                                                                  char _license[] SEC("license") = "GPL";
                                                                                  int _version SEC("version") = 99;
                                                                                  

                                                                                  and this is my user function I assigned to perf_buffer_opts

                                                                                  static void print_bpf_output(void *ctx, int cpu, void *data, __u32 size)
                                                                                  {
                                                                                      struct {
                                                                                          int pid;
                                                                                          char cookie[10];
                                                                                      } *e = data;
                                                                                  

                                                                                  and this is the full code. so can anyone please tell what I am doing wrong why is saying invalid argument

                                                                                  libbpf: map 'my_map': failed to create: Invalid argument(-22)
                                                                                  libbpf: failed to load object './trace_output_kern.o'
                                                                                  ERROR: loading BPF object file failed
                                                                                  root@
                                                                                  

                                                                                  full userspace code

                                                                                  // SPDX-License-Identifier: GPL-2.0-only
                                                                                  #include 
                                                                                  #include 
                                                                                  #include 
                                                                                  #include 
                                                                                  #include 
                                                                                  #include 
                                                                                  
                                                                                  
                                                                                  //create .o file root@this:/home/ubuntu/Desktop/ebpf/kern# clang -I /lib/modules/5.14.1/build -I /usr/include/bpf/ -O2 -Wall -c trace_output_user.c
                                                                                  
                                                                                  static __u64 time_get_ns(void)
                                                                                  {
                                                                                      struct timespec ts;
                                                                                  
                                                                                      clock_gettime(CLOCK_MONOTONIC, &ts);
                                                                                      return ts.tv_sec * 1000000000ull + ts.tv_nsec;
                                                                                  }
                                                                                  
                                                                                  static __u64 start_time;
                                                                                  static __u64 cnt;
                                                                                  
                                                                                  #define MAX_CNT 100000ll
                                                                                  
                                                                                  static void print_bpf_output(void *ctx, int cpu, void *data, __u32 size)
                                                                                  {
                                                                                      struct {
                                                                                          int pid;
                                                                                          char cookie[10];
                                                                                      } *e = data;
                                                                                  
                                                                                      if (e->cookie != 0x12345678) {
                                                                                          printf("BUG pid %llx cookie %s sized %d\n",
                                                                                                 e->pid, e->cookie, size);
                                                                                          return;
                                                                                      }
                                                                                  
                                                                                      cnt++;
                                                                                  
                                                                                      if (cnt == MAX_CNT) {
                                                                                          printf("recv %lld events per sec\n",
                                                                                                 MAX_CNT * 1000000000ll / (time_get_ns() - start_time));
                                                                                          return;
                                                                                      }
                                                                                  }
                                                                                  
                                                                                  int main(int argc, char **argv)
                                                                                  {
                                                                                      struct perf_buffer_opts pb_opts = {};
                                                                                      struct bpf_link *link = NULL;
                                                                                      struct bpf_program *prog;
                                                                                      struct perf_buffer *pb;
                                                                                      struct bpf_object *obj;
                                                                                      int map_fd, ret = 0;
                                                                                      char filename[256];
                                                                                      FILE *f;
                                                                                  
                                                                                      //snprintf(filename, sizeof(filename), "..o", argv[0]);
                                                                                      obj = bpf_object__open_file("./trace_output_kern.o", NULL);
                                                                                      if (libbpf_get_error(obj)) {
                                                                                          fprintf(stderr, "ERROR: opening BPF object file failed\n");
                                                                                          return 0;
                                                                                      }
                                                                                  
                                                                                      /* load BPF program */
                                                                                      if (bpf_object__load(obj)) {
                                                                                          fprintf(stderr, "ERROR: loading BPF object file failed\n");
                                                                                          goto cleanup;
                                                                                      }
                                                                                  
                                                                                      map_fd = bpf_object__find_map_fd_by_name(obj, "my_map");
                                                                                      if (map_fd < 0) {
                                                                                          fprintf(stderr, "ERROR: finding a map in obj file failed\n");
                                                                                          goto cleanup;
                                                                                      }
                                                                                  
                                                                                      prog = bpf_object__find_program_by_name(obj, "bpf_prog1");
                                                                                      if (libbpf_get_error(prog)) {
                                                                                          fprintf(stderr, "ERROR: finding a prog in obj file failed\n");
                                                                                          goto cleanup;
                                                                                      }
                                                                                  
                                                                                      link = bpf_program__attach(prog);
                                                                                      if (libbpf_get_error(link)) {
                                                                                          fprintf(stderr, "ERROR: bpf_program__attach failed\n");
                                                                                          link = NULL;
                                                                                          goto cleanup;
                                                                                      }
                                                                                  
                                                                                      pb_opts.sample_cb = print_bpf_output;
                                                                                      pb = perf_buffer__new(map_fd, 8, &pb_opts);
                                                                                      ret = libbpf_get_error(pb);
                                                                                      if (ret) {
                                                                                          printf("failed to setup perf_buffer: %d\n", ret);
                                                                                          return 1;
                                                                                      }
                                                                                  
                                                                                      f = popen("taskset 1 dd if=/dev/zero of=/dev/null", "r");
                                                                                      (void) f;
                                                                                  
                                                                                      start_time = time_get_ns();
                                                                                      while ((ret = perf_buffer__poll(pb, 1000)) >= 0 && cnt < MAX_CNT) {
                                                                                      }
                                                                                      kill(0, SIGINT);
                                                                                  
                                                                                  cleanup:
                                                                                      bpf_link__destroy(link);
                                                                                      bpf_object__close(obj);
                                                                                      return ret;
                                                                                  }
                                                                                  

                                                                                  ANSWER

                                                                                  Answered 2021-Dec-17 at 17:07

                                                                                  The key and value should be __u32:

                                                                                  struct {
                                                                                      __uint(type, BPF_MAP_TYPE_PERF_EVENT_ARRAY);
                                                                                      __uint(key_size, sizeof(__u32));
                                                                                      __uint(value_size, sizeof(__u32));
                                                                                  } my_map SEC(".maps");
                                                                                  

                                                                                  And you can then push your events to that map as usual:

                                                                                  bpf_perf_event_output(ctx, &my_map, 0, &data, sizeof(data));
                                                                                  

                                                                                  The bpf_perf_event_output helper takes the size of events as argument, so it doesn't need to be a static parameter in the map.

                                                                                  Source https://stackoverflow.com/questions/70394743

                                                                                  QUESTION

                                                                                  I have a function call in one program and this function is depreciated.Is there any newer version that I can use in my code | perf_buffer__new in ebpf
                                                                                  Asked 2022-Jan-10 at 17:07

                                                                                  I have this function which is depreciated. First how one can find the new alternative to functions that are depreciated. the function exist in libbpf library and perf_buffer__new is the exact name. so basically as the name suggest its used to create perf buffer to share info between userspace and kernel. First I like to know is perf buffers are only specific to ebpf filters or not. not means I can use perf buffers in anything. for example if I have some driver code so I just add perf buffer to have info shared between some userspace app and the driver. so some searching on the web I found it specifically link to ebpf, is this true?

                                                                                  So this is my code that uses call to perf_buffer__new but that function is depreciated, this function in libbpf's libbpf.h header file declarations is commented out

                                                                                  So I like to new what is the new alternative that I can use in my code, if there is a change in api then i like to let u know that I am trying share buffer parameter in SEC("kprobe/__x64_sys_recvfrom") to userspace for that I have used PT_REGS_PARM2 and bpf_probe_read_kernel to and included the parameter in map data. So if api is changed then how to accomplish this this is my userspace and ebpf program

                                                                                  Userspace.c

                                                                                      // SPDX-License-Identifier: GPL-2.0-only
                                                                                  #include 
                                                                                  #include 
                                                                                  #include 
                                                                                  #include 
                                                                                  #include 
                                                                                  #include 
                                                                                  
                                                                                  
                                                                                  //create .o file root@this:/home/ubuntu/Desktop/ebpf/kern# clang -I /lib/modules/5.14.1/build -I /usr/include/bpf/ -O2 -Wall -c trace_output_user.c
                                                                                  
                                                                                  static __u64 time_get_ns(void)
                                                                                  {
                                                                                      struct timespec ts;
                                                                                  
                                                                                      clock_gettime(CLOCK_MONOTONIC, &ts);
                                                                                      return ts.tv_sec * 1000000000ull + ts.tv_nsec;
                                                                                  }
                                                                                  
                                                                                  static __u64 start_time;
                                                                                  static __u64 cnt;
                                                                                  
                                                                                  #define MAX_CNT 100000ll
                                                                                  
                                                                                  static void print_bpf_output(void *ctx, int cpu, void *data, __u32 size)
                                                                                  {
                                                                                      struct {
                                                                                          int pid;
                                                                                          char cookie[90];
                                                                                          char *buf;
                                                                                          } *e = data;
                                                                                          int i=0;
                                                                                      printf("hello\n");
                                                                                      
                                                                                      printf(" _____________________________________________________%d \n________%s\n",e->pid,e->buf);
                                                                                      i++;
                                                                                  
                                                                                  
                                                                                      //printf("received map value = %s\n",e->cookie);
                                                                                      /*if (e->cookie != 0x12345678) {
                                                                                          printf("BUG pid %llx cookie %d sized %d\n",
                                                                                                 e->pid, e->cookie, size);
                                                                                          return;
                                                                                      }
                                                                                  
                                                                                      cnt++;
                                                                                  
                                                                                      if (cnt == MAX_CNT) {
                                                                                          printf("recv %lld events per sec\n",
                                                                                                 MAX_CNT * 1000000000ll / (time_get_ns() - start_time));
                                                                                          return;
                                                                                      }*/
                                                                                  }
                                                                                  
                                                                                  int main(int argc, char **argv)
                                                                                  {
                                                                                      struct perf_buffer_opts pb_opts = {};
                                                                                      struct bpf_link *link = NULL;
                                                                                      struct bpf_program *prog;
                                                                                      struct perf_buffer *pb;
                                                                                      struct bpf_object *obj;
                                                                                      int map_fd, ret = 0;
                                                                                      char filename[256];
                                                                                      FILE *f;
                                                                                  
                                                                                      //snprintf(filename, sizeof(filename), "..o", argv[0]);
                                                                                      obj = bpf_object__open_file("./kprobe_send.o", NULL);
                                                                                      if (libbpf_get_error(obj)) {
                                                                                          fprintf(stderr, "ERROR: opening BPF object file failed\n");
                                                                                          return 0;
                                                                                      }
                                                                                  
                                                                                      /* load BPF program */
                                                                                      if (bpf_object__load(obj)) {
                                                                                          fprintf(stderr, "ERROR: loading BPF object file failed\n");
                                                                                          goto cleanup;
                                                                                      }
                                                                                  
                                                                                      map_fd = bpf_object__find_map_fd_by_name(obj, "my_map");
                                                                                      if (map_fd < 0) {
                                                                                          fprintf(stderr, "ERROR: finding a map in obj file failed\n");
                                                                                          goto cleanup;
                                                                                      }
                                                                                      printf("before\n");
                                                                                      prog = bpf_object__find_program_by_name(obj, "bpf_prog1");
                                                                                      if (libbpf_get_error(prog)) {
                                                                                          fprintf(stderr, "ERROR: finding a prog in obj file failed\n");
                                                                                          goto cleanup;
                                                                                      }
                                                                                      printf("after\n");
                                                                                  
                                                                                      link = bpf_program__attach(prog);
                                                                                          printf("after\n");
                                                                                      if (libbpf_get_error(link)) {
                                                                                          fprintf(stderr, "ERROR: bpf_program__attach failed\n");
                                                                                          link = NULL;
                                                                                          goto cleanup;
                                                                                      }
                                                                                      printf("after\n");
                                                                                      pb_opts.sample_cb = print_bpf_output;
                                                                                      pb = perf_buffer__new_deprecated(map_fd, 8, &pb_opts);//error
                                                                                      printf("after\n");
                                                                                      ret = libbpf_get_error(pb);
                                                                                      if (ret) {
                                                                                          printf("failed to setup perf_buffer: %d\n", ret);
                                                                                          return 1;
                                                                                      }
                                                                                  
                                                                                      f = popen("taskset 1 dd if=/dev/zero of=/dev/null", "r");
                                                                                      (void) f;
                                                                                  
                                                                                      start_time = time_get_ns();
                                                                                      while ((ret = perf_buffer__poll(pb, 1000)) >= 0 && cnt < MAX_CNT) {
                                                                                      }
                                                                                      kill(0, SIGINT);
                                                                                  
                                                                                  cleanup:
                                                                                      bpf_link__destroy(link);
                                                                                      bpf_object__close(obj);
                                                                                      return ret;
                                                                                  }
                                                                                  

                                                                                  Kernel.c

                                                                                  #include 
                                                                                  #include 
                                                                                  #include 
                                                                                  #include 
                                                                                  #include 
                                                                                  #include 
                                                                                  #include 
                                                                                  #include 
                                                                                  #include 
                                                                                  #include 
                                                                                  #include 
                                                                                  #define RAND_MAX 0x7fff
                                                                                  #define PERF_SAMPLE_RAW  1U << 0
                                                                                  #define randrange(N) rand() / (RAND_MAX/(N) + 1)
                                                                                  #define MAX 100000000        /* Values will be in the range (1 .. MAX) */
                                                                                  
                                                                                  
                                                                                  struct {
                                                                                      __uint(type, BPF_MAP_TYPE_PERF_EVENT_ARRAY);
                                                                                      __uint(key_size, sizeof(int));
                                                                                      __uint(value_size, sizeof(int));
                                                                                      __uint(max_entries, 100);
                                                                                  } my_map SEC(".maps");
                                                                                  
                                                                                  SEC("kprobe/__x64_sys_recvfrom")
                                                                                  int bpf_prog1(struct pt_regs *ctx)
                                                                                  {
                                                                                  
                                                                                      static int vektor[100000000];
                                                                                      int candidates[MAX];
                                                                                      int i;
                                                                                      long key;
                                                                                  
                                                                                      //srand(time(NULL));   /* Seed the random number generator. */
                                                                                  
                                                                                      /*for (i=0; i 128 && sd.args[2] <= 1024) {
                                                                                          char fmt[] = "read(fd=%d, buf=%p, size=%d)\n";
                                                                                          bpf_trace_printk(fmt, sizeof(fmt),
                                                                                                   sd.args[0], sd.args[1], sd.args[2]);
                                                                                          data.ptr=(char *)sd.args[1];         
                                                                                  //      memcpy(data.ptr,sd.args[1],sizeof(char)*220);        
                                                                                      }
                                                                                  
                                                                                          
                                                                                          
                                                                                  
                                                                                      //data.pid =count;// bpf_get_current_pid_tgid();
                                                                                      //if(buf==NULL)
                                                                                      //memcpy(data.cookie,buf,20);
                                                                                      //data.ptr=ptr; 
                                                                                   //     data.cookie[0]=buf[0];
                                                                                      //bpf_get_current_comm(&data.cookie, sizeof(data.cookie));
                                                                                      
                                                                                      //key=vektor[i];
                                                                                      //bpf_map_update_elem(fd,&key,&data,BPF_ANY);
                                                                                      //bpf_perf_event_output(ctx, &my_map, 1, &data, sizeof(data));
                                                                                      
                                                                                      return 0;
                                                                                  }
                                                                                  
                                                                                  char _license[] SEC("license") = "GPL";
                                                                                  int _version SEC("version") = 99;
                                                                                  

                                                                                  when I compile and link the program userspace with root@this:/home/ubuntu/Desktop/ebpf/Linux-exFilter-main/pkg/probe/bpf# clang -v trace_output_user.c -o trace -lbpf

                                                                                  I get error that and warning

                                                                                  trace_output_user.c:101:7: warning: 'perf_buffer__new_deprecated' is deprecated: libbpf v0.7+: use new variant of perf_buffer__new() instead [-Wdeprecated-declarations]
                                                                                          pb = perf_buffer__new_deprecated(map_fd, 8, &pb_opts);
                                                                                               ^
                                                                                  /usr/include/bpf/libbpf.h:949:12: note: 'perf_buffer__new_deprecated' has been explicitly marked deprecated here
                                                                                  LIBBPF_API LIBBPF_DEPRECATED_SINCE(0, 7, "use new variant of perf_buffer__new() instead")
                                                                                             ^
                                                                                  /usr/include/bpf/libbpf_common.h:24:4: note: expanded from macro 'LIBBPF_DEPRECATED_SINCE'
                                                                                                  (LIBBPF_DEPRECATED("libbpf v" # major "." # minor "+: " msg))
                                                                                                   ^
                                                                                  /usr/include/bpf/libbpf_common.h:19:47: note: expanded from macro 'LIBBPF_DEPRECATED'
                                                                                  #define LIBBPF_DEPRECATED(msg) __attribute__((deprecated(msg)))
                                                                                                                                ^
                                                                                  1 warning generated.
                                                                                   "/usr/bin/ld" -z relro --hash-style=gnu --build-id --eh-frame-hdr -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o trace /usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../x86_64-linux-gnu/crt1.o /usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../x86_64-linux-gnu/crti.o /usr/bin/../lib/gcc/x86_64-linux-gnu/10/crtbegin.o -L/usr/bin/../lib/gcc/x86_64-linux-gnu/10 -L/usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../x86_64-linux-gnu -L/usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../lib64 -L/lib/x86_64-linux-gnu -L/lib/../lib64 -L/usr/lib/x86_64-linux-gnu -L/usr/lib/../lib64 -L/usr/lib/x86_64-linux-gnu/../../lib64 -L/usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../.. -L/usr/lib/llvm-12/bin/../lib -L/lib -L/usr/lib /tmp/trace_output_user-ec780e.o -lbpf -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /usr/bin/../lib/gcc/x86_64-linux-gnu/10/crtend.o /usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../x86_64-linux-gnu/crtn.o
                                                                                  /usr/bin/ld: /tmp/trace_output_user-ec780e.o: in function `main':
                                                                                  trace_output_user.c:(.text+0x1e2): undefined reference to `perf_buffer__new_deprecated'
                                                                                  

                                                                                  some details perf_buffer__new_deprecated and perf_buffer__new are depreciated in latest version of libbpf My kernel version is 5.14.1

                                                                                  ANSWER

                                                                                  Answered 2022-Jan-10 at 17:07

                                                                                  1. you are explicitly using perf_buffer__new_deprecated in your code - don't do this: Use perf_buffer_new instead. You should never call a function that already has 'deprecated' in it's name.

                                                                                  2. Take a look in the header: libbpf/libbpf.h

                                                                                  perf_buffer_new is defined like this:

                                                                                  #define perf_buffer__new(...) ___libbpf_overload(___perf_buffer_new, __VA_ARGS__)
                                                                                  
                                                                                  #define ___perf_buffer_new6(map_fd, page_cnt, sample_cb, lost_cb, ctx, opts) \
                                                                                      perf_buffer__new(map_fd, page_cnt, sample_cb, lost_cb, ctx, opts)
                                                                                  
                                                                                  #define ___perf_buffer_new3(map_fd, page_cnt, opts) \
                                                                                      perf_buffer__new_deprecated(map_fd, page_cnt, opts)
                                                                                  

                                                                                  So there are 2 functions:

                                                                                  • Old: pef_buffer_new with 3 arguments
                                                                                  • New: perf_buffer_new with 6 arguments.

                                                                                  With the macros, libbpf makes old code compile, too, while telling you to change your function call. You are using the old version right now (with 3 arguments). Switch to the new version with 6 arguments, as the 3-arguments-variant will be removed.

                                                                                  The new function (see libbpf/libbpf.h):

                                                                                  /**
                                                                                   * @brief **perf_buffer__new()** creates BPF perfbuf manager for a specified
                                                                                   * BPF_PERF_EVENT_ARRAY map
                                                                                   * @param map_fd FD of BPF_PERF_EVENT_ARRAY BPF map that will be used by BPF
                                                                                   * code to send data over to user-space
                                                                                   * @param page_cnt number of memory pages allocated for each per-CPU buffer
                                                                                   * @param sample_cb function called on each received data record
                                                                                   * @param lost_cb function called when record loss has occurred
                                                                                   * @param ctx user-provided extra context passed into *sample_cb* and *lost_cb*
                                                                                   * @return a new instance of struct perf_buffer on success, NULL on error with
                                                                                   * *errno* containing an error code
                                                                                   */
                                                                                  LIBBPF_API struct perf_buffer *
                                                                                  perf_buffer__new(int map_fd, size_t page_cnt,
                                                                                           perf_buffer_sample_fn sample_cb, perf_buffer_lost_fn lost_cb, void *ctx,
                                                                                           const struct perf_buffer_opts *opts);
                                                                                  

                                                                                  You can find the definitions for sample_cb and lost_cb in the header as well: From above, we know sample_cb has the type perf_buffer_sample_fn. For the other callback, it is similar. Both are defined in libbpf.h:

                                                                                  typedef void (*perf_buffer_sample_fn)(void *ctx, int cpu,
                                                                                                        void *data, __u32 size);
                                                                                  typedef void (*perf_buffer_lost_fn)(void *ctx, int cpu, __u64 cnt);
                                                                                  

                                                                                  See libbpf/libbpf.h

                                                                                  So a valid callback function could be void myCallbackForNewData(void* ctx, int cpu, void*data, __u32 size) {} Be aware that ctx* has nothing to do with BPF - it is something you can freely define in perf_buffer__new. This is useful if you use the same handler for multiple perf_buffers. Otherwise, you can just enter NULL.

                                                                                  Source https://stackoverflow.com/questions/70417623

                                                                                  Community Discussions, Code Snippets contain sources that include Stack Exchange Network

                                                                                  Vulnerabilities

                                                                                  No vulnerabilities reported

                                                                                  Install libbpf

                                                                                  You can download it from GitHub.

                                                                                  Support

                                                                                  Please check out [libbpf-bootstrap](https://github.com/libbpf/libbpf-bootstrap) and [the companion blog post](https://nakryiko.com/posts/libbpf-bootstrap/) for the examples of building BPF applications with libbpf. [libbpf-tools](https://github.com/iovisor/bcc/tree/master/libbpf-tools) are also a good source of the real-world libbpf-based tracing tools. See also ["BPF CO-RE reference guide"](https://nakryiko.com/posts/bpf-core-reference-guide/) for the coverage of practical aspects of building BPF CO-RE applications and ["BPF CO-RE"](https://nakryiko.com/posts/bpf-portability-and-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 bpf@vger.kernel.org mailing list. You can subscribe to it [here](http://vger.kernel.org/vger-lists.html#bpf) and search its archive [here](https://lore.kernel.org/bpf/). Please search the archive before asking new questions. It very well might be that this was already addressed or answered before. bpf@vger.kernel.org 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. Build [![Github Actions Builds & Tests](https://github.com/libbpf/libbpf/actions/workflows/test.yml/badge.svg)](https://github.com/libbpf/libbpf/actions/workflows/test.yml) [![Total alerts](https://img.shields.io/lgtm/alerts/g/libbpf/libbpf.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/libbpf/libbpf/alerts/) [![Coverity](https://img.shields.io/coverity/scan/18195.svg)](https://scan.coverity.com/projects/libbpf) [![OSS-Fuzz Status](https://oss-fuzz-build-logs.storage.googleapis.com/badges/libbpf.svg)](https://oss-fuzz-build-logs.storage.googleapis.com/index.html#libbpf).
                                                                                  Find more information at:
                                                                                  Find, review, and download reusable Libraries, Code Snippets, Cloud APIs from over 650 million Knowledge Items
                                                                                  Find more libraries
                                                                                  Explore Kits - Develop, implement, customize Projects, Custom Functions and Applications with kandi kits​
                                                                                  Save this library and start creating your kit

                                                                                  Share this Page

                                                                                  share link

                                                                                  Consider Popular Recommender System Libraries

                                                                                  recommenders

                                                                                  by microsoft

                                                                                  gorse

                                                                                  by zhenghaoz

                                                                                  DeepCTR

                                                                                  by shenweichen

                                                                                  Surprise

                                                                                  by NicolasHug

                                                                                  lightfm

                                                                                  by lyst

                                                                                  Try Top Libraries by libbpf

                                                                                  libbpf-rs

                                                                                  by libbpfRust

                                                                                  bpftool

                                                                                  by libbpfC

                                                                                  libbpf-sys

                                                                                  by libbpfRust

                                                                                  blazesym

                                                                                  by libbpfRust

                                                                                  Compare Recommender System Libraries with Highest Support

                                                                                  lightfm

                                                                                  by lyst

                                                                                  spotlight

                                                                                  by maciejkula

                                                                                  recommenders

                                                                                  by microsoft

                                                                                  DeepCTR

                                                                                  by shenweichen

                                                                                  implicit

                                                                                  by benfred

                                                                                  Find, review, and download reusable Libraries, Code Snippets, Cloud APIs from over 650 million Knowledge Items
                                                                                  Find more libraries
                                                                                  Explore Kits - Develop, implement, customize Projects, Custom Functions and Applications with kandi kits​
                                                                                  Save this library and start creating your kit