#include #include #include #include #include #include #include #ifdef SUPPORT_BPF #include "bpf_config_user.h" #define MIN(a, b) ((a) > (b) ? (b) : (a)) struct bpf_obj_ctx { char obj_file[1024]; struct bpf_config config; int prog_fd; struct bpf_object *prog_obj; }; void bpf_obj_unload(struct bpf_obj_ctx *ctx) { if (ctx) { if (ctx->prog_fd > 0) { close(ctx->prog_fd); } if (ctx->prog_obj) { bpf_object__close(ctx->prog_obj); ctx->prog_obj = NULL; } free(ctx); ctx = NULL; } } /* * queue_num : same as worker thread number * hash_mode : 2: hash with src/dst addr * 4: hash with src/dst addr and src/dst port * debug_log : 0 for disable(only use for debug, printf bpf debug log(cat /sys/kernel/debug/tracing/trace_pipe) */ struct bpf_obj_ctx *bpf_obj_load(const char *obj_file, uint32_t queue_num, uint32_t hash_mode, uint32_t debug_log) { struct bpf_obj_ctx *ctx = (struct bpf_obj_ctx *)calloc(1, sizeof(struct bpf_obj_ctx)); strncpy(ctx->obj_file, obj_file, MIN(strlen(obj_file), sizeof(ctx->obj_file))); bpf_config_set_queue_num(&ctx->config, queue_num); bpf_config_set_hash_mode(&ctx->config, hash_mode); bpf_config_set_debug_log(&ctx->config, debug_log); #if (LIBBPF_MAJOR_VERSION > 0 || (LIBBPF_MAJOR_VERSION == 0 && LIBBPF_MINOR_VERSION >= 7)) struct bpf_program *prog; ctx->prog_obj = bpf_object__open_file(ctx->obj_file, NULL); if (ctx->prog_obj == NULL) { printf("ERROR: Unable to open bpf object %s, %s.\n", ctx->obj_file, strerror(errno)); goto error; } prog = bpf_object__find_program_by_name(ctx->prog_obj, "bpf_tun_rss_steering"); if (!prog) { printf("ERROR: Unable to get bpf program from object %s, %s.\n", ctx->obj_file, strerror(errno)); goto error; } bpf_program__set_type(prog, BPF_PROG_TYPE_SOCKET_FILTER); if (bpf_object__load(ctx->prog_obj)) { printf("ERROR: Unable to load bpf object %s, %s.\n", ctx->obj_file, strerror(errno)); goto error; } ctx->prog_fd = bpf_program__fd(prog); if (ctx->prog_fd < 0) { printf("ERROR: Unable to get bpf program fd from object %s, %s.\n", ctx->obj_file, strerror(errno)); goto error; } #else if (bpf_prog_load(ctx->obj_file, BPF_PROG_TYPE_SOCKET_FILTER, &ctx->prog_obj, &ctx->prog_fd) < 0) { printf("ERROR: Unable to load bpf object %s, %s.\n", ctx->obj_file, strerror(errno)); goto error; } #endif if (bpf_config_update_map(&ctx->config, ctx->prog_obj) == -1) { goto error; } return ctx; error: bpf_obj_unload(ctx); return NULL; } /* * return 0 : success * return -1 : error */ int bpf_obj_attach(struct bpf_obj_ctx *ctx, int fd) { if (ctx && ctx->prog_fd > 0) { if (ioctl(fd, TUNSETSTEERINGEBPF, (void *)&ctx->prog_fd) == -1) { printf("ERROR: Unable to set bpf on sockfd %d, %s.\n", fd, strerror(errno)); return -1; } else { printf("Set TUNSETSTEERINGEBPF on fd: %d\n", fd); return 0; } } else { return -1; } } #else struct bpf_obj_ctx { }; #include void bpf_obj_unload(struct bpf_obj_ctx *ctx) { printf("ERROR: BPF feature not support on current system\n"); } struct bpf_obj_ctx *bpf_obj_load(const char *obj_file, uint32_t queue_num, uint32_t hash_mode, uint32_t debug_log) { printf("ERROR: BPF feature not support on current system\n"); return NULL; } int bpf_obj_attach(struct bpf_obj_ctx *ctx, int fd) { printf("ERROR: BPF feature not support on current system\n"); return -1; } #endif