目录
加载BPF程序
函数原型
/* bpf_object__open() creates a bpf_object by opening the BPF ELF object file pointed to by the passed path and loading it into memory. Parameters: path – BPF object file path. Returns: pointer to the new bpf_object; or NULL is returned on error, error code is stored in errno */ LIBBPF_API struct bpf_object * bpf_object__open (const char *path) /* bpf_object__open_file() creates a bpf_object by opening the BPF ELF object file pointed to by the passed path and loading it into memory. Parameters: path – BPF object file path opts – options for how to load the bpf object, this parameter is optional and can be set to NULL Returns: pointer to the new bpf_object; or NULL is returned on error, error code is stored in errno */ LIBBPF_API struct bpf_object * bpf_object__open_file (const char *path, const struct bpf_object_open_opts *opts) /* bpf_object__open_mem() creates a bpf_object by reading the BPF objects raw bytes from a memory buffer containing a valid BPF ELF object file. Parameters: obj_buf – pointer to the buffer containing ELF file bytes obj_buf_sz – number of bytes in the buffer opts – options for how to load the bpf object Returns: pointer to the new bpf_object; or NULL is returned on error, error code is stored in errno */ LIBBPF_API struct bpf_object * bpf_object__open_mem (const void *obj_buf, size_t obj_buf_sz, const struct bpf_object_open_opts *opts)
代码Demo
#include <linux/bpf.h> #ifndef __section # define __section(NAME) \ __attribute__((section(NAME), used)) #endif __section("classifier") int bpf_prog(void *ctx) { return 1; } char __license[] __section("license") = "GPL";
clang -O2 -target bpf -c example.c -o example.bpf.o
#include <stdio.h> #include <stdlib.h> #include <sys/resource.h> // 添加这个头文件以使用 setrlimit #include <bpf/libbpf.h> int main() { struct bpf_object *obj; const char *filename = "example.bpf.o"; int err; // 设置 RLIMIT_MEMLOCK 为无限制 struct rlimit rlim = {RLIM_INFINITY, RLIM_INFINITY}; if (setrlimit(RLIMIT_MEMLOCK, &rlim)) { perror("Failed to set RLIMIT_MEMLOCK"); return 1; } // 使用 bpf_object__open obj = bpf_object__open(filename); if (libbpf_get_error(obj)) { fprintf(stderr, "Error loading BPF object from file: %s\n", filename); return 1; } // 使用 bpf_object__open_file obj = bpf_object__open_file(filename, NULL); if (libbpf_get_error(obj)) { fprintf(stderr, "Error loading BPF object from file: %s\n", filename); return 1; } // 使用 bpf_object__open_mem 加载内存中的 BPF 对象 // 读取 BPF 对象文件到内存中 FILE *file = fopen(filename, "rb"); if (file == NULL) { perror("Failed to open BPF object file"); return 1; } fseek(file, 0, SEEK_END); size_t obj_buf_sz = ftell(file); fseek(file, 0, SEEK_SET); void *obj_buf = malloc(obj_buf_sz); if (obj_buf == NULL) { perror("Failed to allocate memory for BPF object buffer"); fclose(file); return 1; } if (fread(obj_buf, 1, obj_buf_sz, file) != obj_buf_sz) { perror("Failed to read BPF object file"); free(obj_buf); fclose(file); return 1; } fclose(file); obj = bpf_object__open_mem(obj_buf, obj_buf_sz, NULL); if (libbpf_get_error(obj)) { fprintf(stderr, "Error loading BPF object from memory\n"); free(obj_buf); return 1; } err = bpf_object__load(obj); if (err) { fprintf(stderr, "Error loading BPF object: %d\n", err); bpf_object__close(obj); return 1; } printf("BPF object loaded successfully\n"); bpf_object__close(obj); return 0; }
makefile
CC = gcc CFLAGS = -Wall -O2 LDFLAGS = -lbpf TARGET = load_bpf SOURCES = load_bpf.c OBJECTS = $(SOURCES:.c=.o) .PHONY: all clean all: $(TARGET) $(TARGET): $(OBJECTS) $(CC) $(OBJECTS) $(LDFLAGS) -o $@ %.o: %.c $(CC) $(CFLAGS) -c $< -o $@ clean: rm -f $(OBJECTS) $(TARGET)
cmake
cmake_minimum_required(VERSION 3.10) project(load_bpf) set(CMAKE_C_STANDARD 99) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -O2") add_executable(load_bpf load_bpf.c) find_library(LIBBPF bpf) if (LIBBPF) target_link_libraries(load_bpf ${LIBBPF}) else() message(FATAL_ERROR "libbpf not found") endif()
将已经打开的 BPF 对象加载到内核中、关闭BPF对象
函数原型
/* bpf_object__load() loads BPF object into kernel. Parameters: obj – Pointer to a valid BPF object instance returned by bpf_object__open*() APIs Returns: 0, on success; negative error code, otherwise, error code is stored in errno */ LIBBPF_API int bpf_object__load (struct bpf_object *obj) /* bpf_object__close() closes a BPF object and releases all resources. Parameters: obj – Pointer to a valid BPF object */ LIBBPF_API void bpf_object__close (struct bpf_object *obj)
代码demo
#include <stdio.h> #include <stdlib.h> #include <sys/resource.h> #include <bpf/libbpf.h> int main() { struct bpf_object *obj; const char *filename = "example.bpf.o"; int err; // 设置 RLIMIT_MEMLOCK 为无限制 struct rlimit rlim = {RLIM_INFINITY, RLIM_INFINITY}; if (setrlimit(RLIMIT_MEMLOCK, &rlim)) { perror("Failed to set RLIMIT_MEMLOCK"); return 1; } // 使用 bpf_object__open_file 打开 BPF 对象文件 obj = bpf_object__open_file(filename, NULL); if (libbpf_get_error(obj)) { fprintf(stderr, "Error loading BPF object from file: %s\n", filename); return 1; } // 使用 bpf_object__load 加载 BPF 对象到内核中 err = bpf_object__load(obj); if (err) { fprintf(stderr, "Error loading BPF object: %d\n", err); bpf_object__close(obj); return 1; } printf("BPF object loaded successfully\n"); // 在此处,可以使用 bpf_object 提供的函数获取程序和地图的文件描述符 // 以便与内核进行交互。例如: // struct bpf_program *prog; // struct bpf_map *map; // int prog_fd, map_fd; // prog = bpf_object__find_program_by_title(obj, "example_prog"); // map = bpf_object__find_map_by_name(obj, "example_map"); // prog_fd = bpf_program__fd(prog); // map_fd = bpf_map__fd(map); bpf_object__close(obj); return 0; }
makefile
CC = gcc CFLAGS = -Wall -Wextra -O2 LIBS = -lbpf TARGET = example SRCS = example.c OBJS = $(SRCS:.c=.o) all: $(TARGET) $(TARGET): $(OBJS) $(CC) $(CFLAGS) -o $@ $^ $(LIBS) %.o: %.c $(CC) $(CFLAGS) -c $< -o $@ clean: rm -f $(OBJS) $(TARGET) .PHONY: all clean
cmake
cmake_minimum_required(VERSION 3.10) project(example LANGUAGES C) set(CMAKE_C_STANDARD 11) set(CMAKE_C_STANDARD_REQUIRED ON) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -O2") find_library(LIBBPF_LIB bpf) add_executable(example example.c) target_link_libraries(example ${LIBBPF_LIB})