#include #include #include #include #include #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 (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; } 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; } }