This repository has been archived on 2025-09-14. You can view files and clone it, but cannot push or open issues or pull requests.
Files
tango-tfe/bpf/bpf_obj.cpp
2024-11-15 18:40:04 +08:00

156 lines
3.8 KiB
C++

#include <errno.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <linux/if_tun.h>
#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 <sys/types.h>
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