### Example usage of BPF_KRETPROBE for kretprobe/do_unlinkat Source: https://docs.ebpf.io/ebpf-library/libbpf/ebpf/BPF_KRETPROBE This C code demonstrates how to use the BPF_KRETPROBE macro to create an eBPF kretprobe program that attaches to the `do_unlinkat` kernel function. It captures the process ID (PID) and the return value of the function, logging them using `bpf_printk`. This example highlights the ease of accessing the return value directly as a parameter. ```c SEC("kretprobe/do_unlinkat") int BPF_KRETPROBE(do_unlinkat_exit, long ret) { pid_t pid; pid = bpf_get_current_pid_tgid() >> 32; bpf_printk("KPROBE EXIT: pid = %d, ret = %ld\n", pid, ret); return 0; } ``` -------------------------------- ### Usage Example: BPF_CORE_READ_USER vs BPF_CORE_READ_USER_INTO (C) Source: https://docs.ebpf.io/ebpf-library/libbpf/ebpf/BPF_CORE_READ_USER_INTO Illustrates the equivalent usage patterns of BPF_CORE_READ_USER and BPF_CORE_READ_USER_INTO macros in C. BPF_CORE_READ_USER_INTO requires the destination to be passed by address. ```c int x = BPF_CORE_READ_USER(s, a.b.c, d.e, f, g); ``` ```c int x; BPF_CORE_READ_USER_INTO(&x, s, a.b.c, d.e, f, g); ``` -------------------------------- ### Libbpf bpf_printk Usage Example (C) Source: https://docs.ebpf.io/ebpf-library/libbpf/ebpf/bpf_printk Demonstrates how to use the `bpf_printk` macro within an eBPF program to send debug messages to the kernel trace log. It shows examples using both `bpf_trace_printk` and `bpf_trace_vprintk` implicitly. ```c SEC("tc") int example_prog(struct __sk_buff *ctx) { // Will use bpf_trace_printk bpf_printk( "Got a packet from interface %d, src: %pi4, dst: %pi4\n", ctx->ingress_ifindex, ctx->remote_ip4, ctx->local_ip4 ); // Will use bpf_trace_vprintk bpf_printk( "Got a packet from interface %d, src: %pi4, dst: %pi4, src port: %d, dst port: %d\n", ctx->ingress_ifindex, ctx->remote_ip4, ctx->local_ip4, ctx->remote_port, ctx->local_port ); return TC_ACT_OK; } ``` -------------------------------- ### Libbpf eBPF BPF_PROG2 macro usage example Source: https://docs.ebpf.io/ebpf-library/libbpf/ebpf/BPF_PROG2 An example demonstrating the usage of the BPF_PROG2 macro in an eBPF program. It shows how to define a program with a normal function signature and arguments that are automatically cast from the context array. ```c SEC("fexit/__sys_bpf") int BPF_PROG2(sys_bpf, int, cmd, bpfptr_t, uattr, unsigned int, size, int, ret) { bpf_printf("BPF syscall returned with: %d", ret); return 0; } ``` -------------------------------- ### Example eBPF program using __ksym for kernel symbol access Source: https://docs.ebpf.io/ebpf-library/libbpf/ebpf/__ksym An example eBPF program demonstrating the usage of the `__ksym` macro. It accesses the `bpf_task_storage_busy` kernel symbol to read its value. The program checks for `CONFIG_PREEMPT` and the current PID before attempting to read the value using `bpf_this_cpu_ptr`. This showcases how `__ksym` facilitates access to kernel variables. ```c // SPDX-License-Identifier: GPL-2.0 /* Copyright (C) 2022. Huawei Technologies Co., Ltd */ #include "vmlinux.h" #include #include extern bool CONFIG_PREEMPT __kconfig __weak; extern const int bpf_task_storage_busy __ksym; char _license[] SEC("license") = "GPL"; int pid = 0; int busy = 0; struct { __uint(type, BPF_MAP_TYPE_TASK_STORAGE); __uint(map_flags, BPF_F_NO_PREALLOC); __type(key, int); __type(value, long); } task SEC(".maps"); SEC("raw_tp/sys_enter") int BPF_PROG(read_bpf_task_storage_busy) { int *value; if (!CONFIG_PREEMPT) return 0; if (bpf_get_current_pid_tgid() >> 32 != pid) return 0; value = bpf_this_cpu_ptr(&bpf_task_storage_busy); if (value) busy = *value; return 0; } ``` -------------------------------- ### Libbpf eBPF BPF_SEQ_PRINTF usage example Source: https://docs.ebpf.io/ebpf-library/libbpf/ebpf/bpf_seq_printf An example demonstrating the usage of the BPF_SEQ_PRINTF macro within an eBPF program. This snippet shows how to print header information and then iterate through task file details, formatting output for each entry. ```c SEC("iter/task_file") int dump_task_file(struct bpf_iter__task_file *ctx) { struct seq_file *seq = ctx->meta->seq; struct task_struct *task = ctx->task; struct file *file = ctx->file; __u32 fd = ctx->fd; if (task == NULL || file == NULL) return 0; if (ctx->meta->seq_num == 0) { count = 0; BPF_SEQ_PRINTF(seq, " tgid gid fd file\n"); } if (tgid == task->tgid && task->tgid != task->pid) count++; if (last_tgid != task->tgid) { last_tgid = task->tgid; unique_tgid_count++; } BPF_SEQ_PRINTF(seq, "%8d %8d %8d %lx\n", task->tgid, task->pid, fd, (long)file->f_op); return 0; } ``` -------------------------------- ### Example eBPF Program Using BPF_CORE_READ Source: https://docs.ebpf.io/ebpf-library/libbpf/ebpf/BPF_CORE_READ An example eBPF program demonstrating the usage of BPF_CORE_READ to access fields within network-related structures like `sk_buff` and `net_device`. It shows how to read device name and packet length, and uses BPF_CORE_READ_STR_INTO for string fields. This snippet is intended for debugging purposes using `bpf_trace_printk`. ```c /* Copyright (c) 2013-2015 PLUMgrid, http://plumgrid.com * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public * License as published by the Free Software Foundation. */ #include "vmlinux.h" #include "net_shared.h" #include #include #include #include /* kprobe is NOT a stable ABI * kernel functions can be removed, renamed or completely change semantics. * Number of arguments and their positions can change, etc. * In such case this bpf+kprobe example will no longer be meaningful */ SEC("kprobe.multi/__netif_receive_skb_core*") int bpf_prog1(struct pt_regs *ctx) { /* attaches to kprobe __netif_receive_skb_core, * looks for packets on loobpack device and prints them * (wildcard is used for avoiding symbol mismatch due to optimization) */ char devname[IFNAMSIZ]; struct net_device *dev; struct sk_buff *skb; int len; bpf_core_read(&skb, sizeof(skb), (void *)PT_REGS_PARM1(ctx)); dev = BPF_CORE_READ(skb, dev); len = BPF_CORE_READ(skb, len); BPF_CORE_READ_STR_INTO(&devname, dev, name); if (devname[0] == 'l' && devname[1] == 'o') { char fmt[] = "skb %p len %d\n"; /* using bpf_trace_printk() for DEBUG ONLY */ bpf_trace_printk(fmt, sizeof(fmt), skb, len); } return 0; } char _license[] SEC("license") = "GPL"; u32 _version SEC("version") = LINUX_VERSION_CODE; ``` -------------------------------- ### Example Usage of Libbpf eBPF __weak macro Source: https://docs.ebpf.io/ebpf-library/libbpf/ebpf/__weak Demonstrates using the __weak macro to mark the `bpf_dynptr_from_xdp` function. It shows how to check for the function's existence using `bpf_ksym_exists` and provides a fallback implementation if the weak symbol is not found. ```c extern int bpf_dynptr_from_xdp(struct xdp_md *x, u64 flags, struct bpf_dynptr *ptr__uninit) __weak __ksym; SEC("xdp.frags") int example_prog(struct xdp_md *ctx) { if (bpf_ksym_exists(bpf_dynptr_from_xdp)) { struct bpf_dynptr ptr; if (bpf_dynptr_from_xdp(ctx, 0, &ptr) < 0) return XDP_DROP; __u8 buf[sizeof(struct ethhdr)]; struct ethhdr *eth = bpf_dynptr_slice(&ptr, buf, sizeof(buf)); if (!eth) return XDP_DROP; if (eth->h_proto == htons(ETH_P_IP)) return XDP_PASS; } else { void *data_end = (void *)(long)ctx->data_end; void *data = (void *)(long)ctx->data; if (data + sizeof(struct ethhdr) > data_end) return XDP_DROP; struct ethhdr *eth = data; if (eth->h_proto == htons(ETH_P_IP)) return XDP_PASS; } } ``` -------------------------------- ### Example Usage of __kconfig in eBPF Source: https://docs.ebpf.io/ebpf-library/libbpf/ebpf/__kconfig Demonstrates how to use the __kconfig macro to access a kernel configuration option (CONFIG_HZ) within an eBPF program. This allows the program to adapt its logic based on the host system's kernel configuration, supporting CO-RE. ```c extern unsigned CONFIG_HZ __kconfig; #define USER_HZ 100 #define NSEC_PER_SEC 1000000000ULL static clock_t jiffies_to_clock_t(unsigned long x) { /* The implementation here tailored to a particular * setting of USER_HZ. */ u64 tick_nsec = (NSEC_PER_SEC + CONFIG_HZ/2) / CONFIG_HZ; u64 user_hz_nsec = NSEC_PER_SEC / USER_HZ; if ((tick_nsec % user_hz_nsec) == 0) { if (CONFIG_HZ < USER_HZ) return x * (USER_HZ / CONFIG_HZ); else return x / (CONFIG_HZ / USER_HZ); } return x * tick_nsec/user_hz_nsec; } ``` -------------------------------- ### Manual Iterator Loop Example (C) Source: https://docs.ebpf.io/ebpf-library/libbpf/ebpf/bpf_for_each Demonstrates the manual process of iterating over kernel data structures using eBPF iterators before the `bpf_for_each` macro. This involves explicit calls to `_new`, `_next`, and `_destroy` functions. ```c SEC("raw_tp/sys_enter") int my_example(const void *ctx) { struct bpf_iter_task task_it; struct task_struct *task_ptr; // Initialize the iterator, request to iterate over all processes on the system bpf_iter_task_new(&task_it, NULL, BPF_TASK_ITER_ALL_PROCS); // Loop until `bpf_iter_task_next` returns NULL while((task_ptr = bpf_iter_task_next(&task_it))) { // Do something with the task pointer if (/* We found the task we are looking for*/) break; } bpf_iter_task_destroy(&task_it); return 0; } ``` -------------------------------- ### Example Usage of BPF_USDT for a USDT Probe Source: https://docs.ebpf.io/ebpf-library/libbpf/ebpf/BPF_USDT This C code demonstrates the usage of the BPF_USDT macro to define an eBPF program attached to a specific USDT tracepoint. It shows how to declare arguments and access them within the probe, along with example logic for counting calls and summing buffer sizes. ```c // SPDX-License-Identifier: GPL-2.0 /* Copyright (c) 2022 Meta Platforms, Inc. and affiliates. */ SEC("usdt/./urandom_read:urand:read_without_sema") int BPF_USDT(urand_read_without_sema, int iter_num, int iter_cnt, int buf_sz) { if (urand_pid != (bpf_get_current_pid_tgid() >> 32)) return 0; __sync_fetch_and_add(&urand_read_without_sema_call_cnt, 1); __sync_fetch_and_add(&urand_read_without_sema_buf_sz_sum, buf_sz); return 0; } ``` -------------------------------- ### Example Usage of bpf_repeat Macro in eBPF Program (C) Source: https://docs.ebpf.io/ebpf-library/libbpf/ebpf/bpf_repeat Demonstrates the usage of the `bpf_repeat` macro within an eBPF program. This example shows how to create a loop that iterates 64 times, with a conditional break if `try_to_do_something()` returns true. This is useful for scenarios requiring a fixed number of attempts or checks. ```c SEC("raw_tp/sys_enter") int iter_next_rcu(const void *ctx) { bpf_repeat(64) { if (try_to_do_something()) break; } } ``` -------------------------------- ### Get BPF Program Info by File Descriptor (C) Source: https://docs.ebpf.io/ebpf-library/libbpf/userspace/bpf_prog_get_info_by_fd The `bpf_prog_get_info_by_fd` function retrieves detailed information about a BPF program. It requires a file descriptor for the program and a buffer to store the program's information. The caller must manage the size of the information buffer. ```c int bpf_prog_get_info_by_fd(int prog_fd, struct bpf_prog_info *info, __u32 *info_len); ``` -------------------------------- ### Get Next BTF ID - C Source: https://docs.ebpf.io/ebpf-library/libbpf/userspace/bpf_btf_get_next_id Provides a low-level C wrapper for the BPF_BTF_GET_NEXT_ID syscall. It takes a starting BTF object ID and returns the next available ID. Success is indicated by a return value of 0, while errors are represented by negative codes. ```c #include #include int bpf_btf_get_next_id(__u32 start_id, __u32 *next_id) { return bpf_btf_get_next_id(start_id, next_id); } ``` -------------------------------- ### Low-Level BPF APIs Source: https://docs.ebpf.io/ebpf-library/libbpf/userspace These APIs, found in `bpf.h`, provide direct interaction with the kernel via the `bpf()` syscall. They are recommended for advanced users who require functionality not covered by the high-level APIs. ```APIDOC ## Low-Level APIs These APIs are wrappers around the `bpf()` syscall and are located in the `bpf.h` header file. Use these only when the high-level APIs do not provide the necessary functionality. ### API List * `libbpf_set_memlock_rlim` * `bpf_map_create` * `bpf_prog_load` * `bpf_btf_load` * `bpf_map_update_elem` * `bpf_map_lookup_elem` * `bpf_map_lookup_elem_flags` * `bpf_map_lookup_and_delete_elem` * `bpf_map_lookup_and_delete_elem_flags` * `bpf_map_delete_elem` * `bpf_map_delete_elem_flags` * `bpf_map_get_next_key` * `bpf_map_freeze` * `bpf_map_delete_batch` * `bpf_map_lookup_batch` * `bpf_map_lookup_and_delete_batch` * `bpf_map_update_batch` * `bpf_obj_pin` * `bpf_obj_pin_opts` * `bpf_obj_get` * `bpf_obj_get_opts` * `bpf_prog_attach` * `bpf_prog_detach` * `bpf_prog_detach2` * `bpf_prog_attach_opts` * `bpf_prog_detach_opts` * `bpf_link_create` * `bpf_link_detach` * `bpf_link_update` * `bpf_iter_create` * `bpf_prog_get_next_id` * `bpf_map_get_next_id` * `bpf_btf_get_next_id` * `bpf_link_get_next_id` * `bpf_prog_get_fd_by_id` * `bpf_prog_get_fd_by_id_opts` * `bpf_map_get_fd_by_id` * `bpf_map_get_fd_by_id_opts` * `bpf_btf_get_fd_by_id` * `bpf_btf_get_fd_by_id_opts` * `bpf_link_get_fd_by_id` * `bpf_link_get_fd_by_id_opts` * `bpf_obj_get_info_by_fd` * `bpf_prog_get_info_by_fd` * `bpf_map_get_info_by_fd` * `bpf_btf_get_info_by_fd` * `bpf_link_get_info_by_fd` * `bpf_prog_query_opts` * `bpf_prog_query` * `bpf_raw_tracepoint_open_opts` * `bpf_raw_tracepoint_open` * `bpf_task_fd_query` * `bpf_enable_stats` * `bpf_prog_bind_map` * `bpf_prog_test_run_opts` * `bpf_token_create` ``` -------------------------------- ### Get BTF Value Type ID for BPF Map (C) Source: https://docs.ebpf.io/ebpf-library/libbpf/userspace/bpf_map__btf_value_type_id Retrieves the BTF type ID for the value associated with a given BPF map. This function takes a pointer to a `bpf_map` structure as input. It returns the BTF type ID of the map's value, or 0 if no BTF type ID is available. The documentation for usage examples is currently incomplete. ```c #include __u32 bpf_map__btf_value_type_id(const struct bpf_map *map); ``` -------------------------------- ### Define libbpf_prog_setup_fn_t Callback Source: https://docs.ebpf.io/ebpf-library/libbpf/userspace/struct-libbpf_prog_handler_opts Defines the function signature for the BPF program initialization callback. This function is called during bpf_object__open and can be used to adjust program properties. ```c typedef int (*libbpf_prog_setup_fn_t)(struct bpf_program *prog, long cookie); ``` -------------------------------- ### Example of reading task parent pointer using bpf_core_read in C Source: https://docs.ebpf.io/ebpf-library/libbpf/ebpf/bpf_core_read Provides a practical example of using `bpf_core_read` to retrieve the parent task pointer from the current task structure in an eBPF program. ```c struct task_struct *task = (void *)bpf_get_current_task(); struct task_struct *parent_task; int err; err = bpf_core_read(&parent_task, sizeof(void *), &task->parent); if (err) { /* handle error */ } /* parent_task contains the value of task->parent pointer */ ``` -------------------------------- ### Libbpf eBPF __arg_arena Macro Definition and Usage Example Source: https://docs.ebpf.io/ebpf-library/libbpf/ebpf/__arg_arena This C code snippet defines the `__arg_arena` macro and provides an example of its usage within an eBPF program. It demonstrates how to tag function arguments to indicate they reside on an arena, which helps the eBPF verifier track memory. The example includes structures for hash tables and elements, along with functions for initialization, lookup, and update, all utilizing arena-allocated memory. ```c /* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ /* Copyright (c) 2024 Meta Platforms, Inc. and affiliates. */ #pragma once #include #include "bpf_arena_alloc.h" #include "bpf_arena_list.h" struct htab_bucket { struct arena_list_head head; }; typedef struct htab_bucket __arena htab_bucket_t; struct htab { htab_bucket_t *buckets; int n_buckets; }; typedef struct htab __arena htab_t; static inline htab_bucket_t *__select_bucket(htab_t *htab, __u32 hash) { htab_bucket_t *b = htab->buckets; cast_kern(b); return &b[hash & (htab->n_buckets - 1)]; } static inline arena_list_head_t *select_bucket(htab_t *htab, __u32 hash) { return &__select_bucket(htab, hash)->head; } struct hashtab_elem { int hash; int key; int value; struct arena_list_node hash_node; }; typedef struct hashtab_elem __arena hashtab_elem_t; static hashtab_elem_t *lookup_elem_raw(arena_list_head_t *head, __u32 hash, int key) { hashtab_elem_t *l; list_for_each_entry(l, head, hash_node) if (l->hash == hash && l->key == key) return l; return NULL; } static int htab_hash(int key) { return key; } __weak int htab_lookup_elem(htab_t *htab __arg_arena, int key) { hashtab_elem_t *l_old; arena_list_head_t *head; cast_kern(htab); head = select_bucket(htab, key); l_old = lookup_elem_raw(head, htab_hash(key), key); if (l_old) return l_old->value; return 0; } __weak int htab_update_elem(htab_t *htab __arg_arena, int key, int value) { hashtab_elem_t *l_new = NULL, *l_old; arena_list_head_t *head; cast_kern(htab); head = select_bucket(htab, key); l_old = lookup_elem_raw(head, htab_hash(key), key); l_new = bpf_alloc(sizeof(*l_new)); if (!l_new) return -ENOMEM; l_new->key = key; l_new->hash = htab_hash(key); l_new->value = value; list_add_head(&l_new->hash_node, head); if (l_old) { list_del(&l_old->hash_node); bpf_free(l_old); } return 0; } void htab_init(htab_t *htab) { void __arena *buckets = bpf_arena_alloc_pages(&arena, NULL, 2, NUMA_NO_NODE, 0); cast_user(buckets); htab->buckets = buckets; htab->n_buckets = 2 * PAGE_SIZE / sizeof(struct htab_bucket); } ``` -------------------------------- ### Create BTF Extension Object using btf_ext__new Source: https://docs.ebpf.io/ebpf-library/libbpf/userspace/btf_ext__new The `btf_ext__new` function creates a new BTF extension object from raw data. It takes a pointer to the raw data and its size as input. It returns a pointer to the newly created BTF extension object or NULL if an error occurs. ```c struct btf_ext *btf_ext__new(const __u8 *data, __u32 size); ``` -------------------------------- ### Initialize Per-CPU Data with __percpu_kptr in eBPF Source: https://docs.ebpf.io/ebpf-library/libbpf/ebpf/__percpu_kptr Demonstrates initializing per-CPU data using the __percpu_kptr macro within an eBPF program. It shows how to create, associate, and manage per-CPU objects using libbpf helper functions like `bpf_percpu_obj_new` and `bpf_kptr_xchg`. ```c #include "bpf_experimental.h" struct val_t { long b, c, d; }; struct elem { long sum; struct val_t __percpu_kptr *pc; }; struct { __uint(type, BPF_MAP_TYPE_ARRAY); __uint(max_entries, 1); __type(key, int); __type(value, struct elem); } array SEC(".maps"); void bpf_rcu_read_lock(void) __ksym; void bpf_rcu_read_unlock(void) __ksym; const volatile int nr_cpus; /* Initialize the percpu object */ SEC("?fentry/bpf_fentry_test1") int BPF_PROG(test_array_map_1) { struct val_t __percpu_kptr *p; struct elem *e; int index = 0; e = bpf_map_lookup_elem(&array, &index); if (!e) return 0; p = bpf_percpu_obj_new(struct val_t); if (!p) return 0; p = bpf_kptr_xchg(&e->pc, p); if (p) bpf_percpu_obj_drop(p); return 0; } ``` -------------------------------- ### Example Usage of BPF_CORE_READ_BITFIELD in eBPF Source: https://docs.ebpf.io/ebpf-library/libbpf/ebpf/BPF_CORE_READ_BITFIELD Demonstrates how to use the BPF_CORE_READ_BITFIELD macro within an eBPF program to extract the 'is_cwnd_limited' bitfield from a tcp_sock structure. This example assumes the necessary structure definitions and helper functions are available. ```c // SPDX-License-Identifier: GPL-2.0 /* Copyright (c) 2019 Facebook */ struct tcp_sock { u32 snd_cwnd; /* Sending congestion window */ /* [...] */ u8 chrono_type : 2, /* current chronograph type */ repair : 1, tcp_usec_ts : 1, /* TSval values in usec */ is_sack_reneg:1, /* in recovery from loss with SACK reneg? */ is_cwnd_limited:1; /* [...] */ u32 max_packets_out; /* max packets_out in last window */ } static inline bool tcp_is_cwnd_limited(const struct sock *sk) { const struct tcp_sock *tp = tcp_sk(sk); /* If in slow start, ensure cwnd grows to twice what was ACKed. */ if (tcp_in_slow_start(tp)) return tp->snd_cwnd < 2 * tp->max_packets_out; return !!BPF_CORE_READ_BITFIELD(tp, is_cwnd_limited); } ``` -------------------------------- ### btf__load_vmlinux_btf Source: https://docs.ebpf.io/ebpf-library/libbpf/userspace/btf__load_vmlinux_btf Loads the BTF (BPF Type Format) object for the currently running kernel. This function returns a pointer to a `struct btf` object representing the kernel's BTF information. ```APIDOC ## btf__load_vmlinux_btf ### Description Loads the BTF (BPF Type Format) object for the currently running kernel. This function returns a pointer to a `struct btf` object representing the kernel's BTF information. ### Method `void` (This is a C function, not a typical HTTP method) ### Endpoint N/A (This is a library function, not a network endpoint) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```c struct btf *btf = btf__load_vmlinux_btf(); if (!btf) { // Handle error } // Use the btf object btf__free(btf); ``` ### Response #### Success Response - **struct btf *** - A pointer to a `struct btf` object on success. #### Response Example ```json { "success": true, "btf_object_pointer": "" } ``` #### Failure Response - **NULL** - Returns `NULL` on failure. #### Response Example ```json { "success": false, "error": "Failed to load kernel BTF" } ``` ``` -------------------------------- ### Example eBPF map definition using LIBBPF_PIN_BY_NAME Source: https://docs.ebpf.io/ebpf-library/libbpf/ebpf/enum-libbpf_pin_type Demonstrates how to use the `LIBBPF_PIN_BY_NAME` enum value within an eBPF map definition. This example shows a hash map configuration where the map is pinned by name in the filesystem. ```c struct { __uint(type, BPF_MAP_TYPE_HASH); __uint(max_entries, 1024); __uint(key_size, sizeof(int)); __uint(value_size, sizeof(long)); __uint(pinning, LIBBPF_PIN_BY_NAME); } SEC(".maps") my_map; ``` -------------------------------- ### Libbpf Version String Source: https://docs.ebpf.io/ebpf-library/libbpf/userspace/libbpf_version_string Retrieves the libbpf version string. ```APIDOC ## GET /libbpf_version_string ### Description Retrieves the libbpf version string. ### Method GET ### Endpoint /libbpf_version_string ### Parameters #### Query Parameters None #### Request Body None ### Request Example None ### Response #### Success Response (200) - **version_string** (string) - Libbpf version as a NULL-terminated string. #### Response Example { "version_string": "0.6.0" } ``` -------------------------------- ### bpf_object__open_file Source: https://docs.ebpf.io/ebpf-library/libbpf/userspace/bpf_object__open_file Opens a BPF ELF object file and loads it into memory, creating a struct bpf_object. ```APIDOC ## bpf_object__open_file ### Description Creates a `struct bpf_object` by opening the BPF ELF object file pointed to by the passed path and loading it into memory. ### Method `struct bpf_object * bpf_object__open_file(const char *path, const struct bpf_object_open_opts *opts);` ### Parameters #### Path Parameters - **path** (const char *) - Required - BPF object file path - **opts** (const struct bpf_object_open_opts *) - Optional - Options for how to load the bpf object, can be set to `NULL` ### Return - pointer to the new `struct bpf_object` on success. - `NULL` on error, with the error code stored in `errno`. ``` -------------------------------- ### Example usage of bpf_htonl in eBPF program Source: https://docs.ebpf.io/ebpf-library/libbpf/ebpf/bpf_htonl An eBPF program example demonstrating the use of `bpf_htonl` to check if a socket is bound to a specific IP address (`192.168.1.254`) and port (`4040`). It utilizes `bpf_htons` for port conversion as well. ```c #define SERV4_IP 0xc0a801feU /* 192.168.1.254 */ #define SERV4_PORT 4040 SEC("cgroup/bind4") int bind_v4_prog(struct bpf_sock_addr *ctx) { struct bpf_sock *sk; sk = ctx->sk; if (!sk) return 0; if (sk->family != AF_INET) return 0; if (ctx->user_ip4 != bpf_htonl(SERV4_IP) || ctx->user_port != bpf_htons(SERV4_PORT)) return 0; return 1; } ``` -------------------------------- ### btf__relocate Function Documentation Source: https://docs.ebpf.io/ebpf-library/libbpf/userspace/btf__relocate Details on the `btf__relocate` function, its parameters, return values, and usage. ```APIDOC ## btf__relocate Function ### Description This function checks the split BTF `btf` for references to base BTF kinds and verifies their compatibility with `base_btf`. If compatible, `btf` is adjusted to be re-parented to `base_btf`, and type IDs and strings are updated accordingly. ### Method Function Call ### Endpoint N/A (Userspace Library Function) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```c // Example usage (conceptual) struct btf *my_btf = btf__parse("path/to/my_btf.bpf.o"); struct btf *base_btf = btf__parse("path/to/base_btf.bpf.o"); if (btf__relocate(my_btf, base_btf) < 0) { // Handle error } // my_btf is now relocated relative to base_btf ``` ### Response #### Success Response (0) - **Return Value** (int) - 0 is returned on success. `btf` is now based on `base_btf`. #### Error Response (Negative Value) - **Return Value** (int) - A negative value indicates an error. The thread-local `errno` variable is set to the error code. #### Response Example ```c // Success: // Return value is 0 // Error: // Return value is negative, e.g., -1, and errno is set. ``` ``` -------------------------------- ### Example Usage of __arg_trusted in eBPF Function Source: https://docs.ebpf.io/ebpf-library/libbpf/ebpf/__arg_trusted Demonstrates the usage of the __arg_trusted macro in a C eBPF program. It shows how to tag a task_struct pointer as trusted and how this is enforced by the verifier at call sites. This example is relevant for uprobes and kernel memory interaction. ```c __weak int subprog_nonnull_task_flavor(struct task_struct___local *task __arg_trusted) { char buf[16]; return bpf_copy_from_user_task(&buf, sizeof(buf), NULL, (void *)task, 0); } SEC("?uprobe.s") int flavor_ptr_nonnull(void *ctx) { struct task_struct *t = bpf_get_current_task_btf(); return subprog_nonnull_task_flavor((void *)t); } ``` -------------------------------- ### Get BPF Link File Descriptor by ID with Options (C) Source: https://docs.ebpf.io/ebpf-library/libbpf/userspace/bpf_link_get_fd_by_id_opts This C function, `bpf_link_get_fd_by_id_opts`, acts as a low-level wrapper for the `BPF_LINK_GET_FD_BY_ID` syscall. It retrieves a file descriptor for a BPF link given its ID and optional configuration flags. The returned file descriptor represents a reference to the BPF link and should be closed when no longer needed. It takes a BPF link ID and a pointer to `struct bpf_get_fd_by_id_opts` as input, returning a file descriptor on success or a negative error code on failure. ```c int bpf_link_get_fd_by_id_opts(__u32 id, const struct bpf_get_fd_by_id_opts *opts); struct bpf_get_fd_by_id_opts { size_t sz; /* size of this struct for forward/backward compatibility */ __u32 open_flags; /* permissions requested for the operation on fd */ size_t :0; }; // Usage example: // int fd = bpf_link_get_fd_by_id_opts(link_id, &opts); // if (fd < 0) { // // handle error // } // // ... use fd ... // close(fd); ``` -------------------------------- ### Get ELF Section Name of BPF Program (C) Source: https://docs.ebpf.io/ebpf-library/libbpf/userspace/bpf_program__section_name Retrieves the ELF section name for a given BPF program. This function takes a pointer to a `bpf_program` struct as input and returns a C-style string representing the section name. It is part of the libbpf library for interacting with BPF programs. ```c const char *bpf_program__section_name(const struct bpf_program *prog); ``` -------------------------------- ### Attach Raw Tracepoint Program with Options (C) Source: https://docs.ebpf.io/ebpf-library/libbpf/userspace/bpf_program__attach_raw_tracepoint_opts Attaches a BPF_PROG_TYPE_RAW_TRACEPOINT program to a specified tracepoint with additional options. It takes the BPF program, tracepoint name, and an options struct as input. Returns a BPF link on success or NULL on error. ```c struct bpf_link * bpf_program__attach_raw_tracepoint_opts(const struct bpf_program *prog, const char *tp_name, struct bpf_raw_tracepoint_opts *opts); ``` -------------------------------- ### Libbpf `user_ring_buffer__submit` Source: https://docs.ebpf.io/ebpf-library/libbpf/userspace/user_ring_buffer__submit Submits a previously reserved sample into the ring buffer. This function is thread-safe and does not require external synchronization for multiple producers. ```APIDOC ## `user_ring_buffer__submit` ### Description Submits a previously reserved sample into the ring buffer. ### Method N/A (This is a C function, not an HTTP endpoint) ### Endpoint N/A ### Parameters #### Path Parameters N/A #### Query Parameters N/A #### Request Body N/A ### Request Example ```c struct user_ring_buffer *rb = user_ring_buffer__new(...); void *sample = user_ring_buffer__reserve(rb, ...); // ... populate sample ... user_ring_buffer__submit(rb, sample); ``` ### Response #### Success Response (void) This function returns void. #### Response Example N/A ``` -------------------------------- ### Example usage of BPF_PROG macro in an eBPF program Source: https://docs.ebpf.io/ebpf-library/libbpf/ebpf/BPF_PROG This C code demonstrates the usage of the `BPF_PROG` macro within an eBPF program. It defines a program named `filter_switch` for `struct_ops/hid_device_event`, which takes a `struct hid_bpf_ctx` as an argument. The example shows how to access data from the context, reserve space in a ring buffer, and commit data to it. ```c SEC("struct_ops/hid_device_event") int BPF_PROG(filter_switch, struct hid_bpf_ctx *hid_ctx) { __u8 *data = hid_bpf_get_data(hid_ctx, 0 /* offset */, 192 /* size */); __u8 *buf; if (!data) return 0; /* EPERM check */ if (current_value != data[152]) { buf = bpf_ringbuf_reserve(&ringbuf, 1, 0); if (!buf) return 0; *buf = data[152]; bpf_ringbuf_commit(buf, 0); current_value = data[152]; } return 0; } ``` -------------------------------- ### Example Usage of Libbpf eBPF `barrier_var` macro Source: https://docs.ebpf.io/ebpf-library/libbpf/ebpf/barrier_var Illustrates the usage of the `barrier_var` macro in eBPF code. This example shows how `barrier_var` can be used to ensure that a 32-bit to 64-bit cast of a variable is performed before the barrier, preventing the compiler from optimizing away or delaying the cast. This is crucial for code patterns where such casts need to be reliably executed. ```c /* Example demonstrating the effect of barrier_var on casting */ unsigned int val32 = ...; unsigned long long val64; // Without barrier_var, compiler might optimize the cast // val64 = (unsigned long long)val32; // With barrier_var, the cast is ensured to happen before the barrier val64 = (unsigned long long)val32; barrier_var(val64); // Now compiler cannot assume val64's value is unchanged before this point ``` -------------------------------- ### Query BPF Programs with `bpf_prog_query` (C) Source: https://docs.ebpf.io/ebpf-library/libbpf/userspace/bpf_prog_query Demonstrates how to use the `bpf_prog_query` function to retrieve BPF programs attached to a target. This function requires a target file descriptor, an attach type, and query flags. It returns program IDs and their count upon success. ```c #include #include #include int main() { int target_fd = /* ... obtain target file descriptor ... */; enum bpf_attach_type type = /* ... specify attach type ... */; __u32 query_flags = 0; __u32 attach_flags; __u32 prog_ids[10]; // Assuming max 10 programs for example __u32 prog_cnt; int ret = bpf_prog_query(target_fd, type, query_flags, &attach_flags, prog_ids, &prog_cnt); if (ret < 0) { fprintf(stderr, "Error querying BPF programs: %d\n", errno); return 1; } printf("Found %u BPF programs attached.\n", prog_cnt); for (__u32 i = 0; i < prog_cnt; i++) { printf(" Program ID: %u\n", prog_ids[i]); } return 0; } ``` -------------------------------- ### bpf_program__attach_trace Source: https://docs.ebpf.io/ebpf-library/libbpf/userspace/bpf_program__attach_trace Attaches a BPF_PROG_TYPE_TRACING program to the system. This function returns a reference to the created BPF link or NULL on error. ```APIDOC ## bpf_program__attach_trace ### Description Attaches a `BPF_PROG_TYPE_TRACING` program. Returns a reference to the newly created BPF link or NULL on error. ### Method `struct bpf_link * bpf_program__attach_trace(const struct bpf_program *prog);` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```c // Example usage (conceptual, requires libbpf setup) struct bpf_program *prog = ...; // Load your BPF program struct bpf_link *link = bpf_program__attach_trace(prog); if (!link) { fprintf(stderr, "Failed to attach trace program: %s\n", strerror(errno)); // Handle error } // Use the link... // bpf_link__destroy(link); ``` ### Response #### Success Response (200) - **struct bpf_link***: A pointer to the newly created BPF link. This link can be used to manage the attached program (e.g., detach it later). #### Response Example ```c // Success: Returns a valid pointer to struct bpf_link // Example: 0x... // Error: Returns NULL and sets errno // Example: NULL ``` ### Error Handling - If the function fails, it returns `NULL` and the `errno` variable is set to indicate the error. ``` -------------------------------- ### Linker Functions Source: https://docs.ebpf.io/ebpf-library/libbpf/userspace Functions for creating and managing BPF linkers. ```APIDOC ## Linker Functions ### Description Functions for creating and managing BPF linkers. ### Functions - `bpf_linker__new` - `bpf_linker__new_fd` - `bpf_linker__add_file` - `bpf_linker__add_fd` - `bpf_linker__add_buf` - `bpf_linker__finalize` - `bpf_linker__free` ``` -------------------------------- ### Attach BPF program to USDT probe (C) Source: https://docs.ebpf.io/ebpf-library/libbpf/userspace/bpf_program__attach_usdt The `bpf_program__attach_usdt` function in libbpf allows attaching a BPF program to a USDT probe. It takes the BPF program, process ID, binary path, USDT provider name, USDT name, and optional settings as parameters. It returns a BPF link on success or NULL on error. ```c struct bpf_link * bpf_program__attach_usdt(const struct bpf_program *prog, pid_t pid, const char *binary_path, const char *usdt_provider, const char *usdt_name, const struct bpf_usdt_opts *opts); ``` -------------------------------- ### Example Usage of BPF_SNPRINTF in an eBPF Program Source: https://docs.ebpf.io/ebpf-library/libbpf/ebpf/bpf_snprintf This C code snippet demonstrates how to use the BPF_SNPRINTF macro within an eBPF program attached to the TC hook. It shows how to format packet information into a string and send it via a ring buffer. The example highlights the macro's ability to handle various data types and provides error checking for buffer allocation. ```c struct { __uint(type, BPF_MAP_TYPE_RINGBUF); __uint(max_entries, 4096); } ringbuf SEC(".maps"); SEC("tc") int example_prog(struct __sk_buff *ctx) { const int size = 100; char *str_out = bpf_ringbuf_reserve(&ringbuf, size, 0); if (!str_out) return TC_ACT_OK; // `len` is the length of the formatted string including NULL-termination char. // if `len` > `size` then the string was truncated. // `len` can also be -EBUSY if the per-CPU memory copy buffer is busy. long len = BPF_SNPRINTF(str_out, size, "Got a packet from interface %d, src: %pi4, dst: %pi4, src port: %d, dst port: %d\n", ctx->ingress_ifindex, ctx->remote_ip4, ctx->local_ip4, ctx->remote_port, ctx->local_port ); bpf_ringbuf_submit(str_out, 0); return TC_ACT_OK; } ``` -------------------------------- ### eBPF Program Example using SEC Macro (C) Source: https://docs.ebpf.io/ebpf-library/libbpf/ebpf/SEC This example demonstrates the usage of the SEC macro to place an eBPF program into the 'xdp' ELF section. This section designation tells libbpf to load the program as type BPF_PROG_TYPE_XDP with attach type BPF_XDP. The function checks packet data for an Ethernet header and returns XDP_PASS if it's an IP packet. ```c SEC("xdp") int example_prog(struct xdp_md *ctx) { void *data_end = (void *)(long)ctx->data_end; void *data = (void *)(long)ctx->data; if (data + sizeof(struct ethhdr) > data_end) return XDP_DROP; struct ethhdr *eth = data; if (eth->h_proto == htons(ETH_P_IP)) return XDP_PASS; } ``` -------------------------------- ### C: bpf_raw_tracepoint_open function definition and usage Source: https://docs.ebpf.io/ebpf-library/libbpf/userspace/bpf_raw_tracepoint_open Provides the C function definition for `bpf_raw_tracepoint_open`, which is a low-level wrapper for the `BPF_RAW_TRACEPOINT_OPEN` syscall. It details the parameters (`name` and `prog_fd`) and the expected return value (file descriptor or error code). The description also advises using higher-level functions like `bpf_program__attach_raw_tracepoint` unless precise control is needed. ```c int bpf_raw_tracepoint_open(const char *name, int prog_fd); // Parameters // name: name of the raw tracepoint // prog_fd: BPF program file descriptor // Return // >0, file descriptor of the raw tracepoint; negative error code, otherwise ``` -------------------------------- ### Libbpf bpf_object__prev_map Source: https://docs.ebpf.io/ebpf-library/libbpf/userspace/bpf_object__prev_map Iterates over the maps in a BPF object in reverse order. Pass NULL as the map to start the iteration from the last map. ```APIDOC ## bpf_object__prev_map ### Description Iterate over the maps in a BPF object in reverse order. ### Method `struct bpf_map * bpf_object__prev_map(const struct bpf_object *obj, const struct bpf_map *map);` ### Parameters #### Path Parameters - None #### Query Parameters - None #### Request Body - None ### Request Example ```c // Example usage (conceptual, actual implementation may vary) struct bpf_object *obj = bpf_object__open_file("your_bpf_program.o", NULL); if (!obj) { // handle error } struct bpf_map *map = NULL; while ((map = bpf_object__prev_map(obj, map))) { // Process the map printf("Map name: %s\n", bpf_map__name(map)); } bpf_object__close(obj); ``` ### Response #### Success Response (200) - **struct bpf_map ***: A pointer to the previous map in the object, or NULL if there are no more maps. #### Response Example ```json { "example": "// Returns a pointer to struct bpf_map or NULL" } ``` ```