Skip to content

Instantly share code, notes, and snippets.

@cs-qyzhang
Last active July 20, 2023 14:04
Show Gist options
  • Select an option

  • Save cs-qyzhang/65278b2392203731103bc6ca9ec26118 to your computer and use it in GitHub Desktop.

Select an option

Save cs-qyzhang/65278b2392203731103bc6ca9ec26118 to your computer and use it in GitHub Desktop.
ubpf library example
// https://klyr.github.io/posts/playing_with_ubpf/
// clang -target bpf -I/usr/include/x86_64-linux-gnu -O2 -g -c double.bpf.c -o double.bpf.o
static int idouble(int a) {
return (a * 2);
}
int bpf_prog(void *ctx) {
int a = *(int *)ctx;
a = idouble(a);
return (a);
}
// build ubpf first, compile this file in build directory:
// gcc -o test_bpf -I./vm test_bpf.c -L./lib -lubpf
#include <stdio.h>
#include <errno.h>
#include <assert.h>
#include "../vm/inc/ubpf.h"
// https://github.com/iovisor/ubpf/blob/main/vm/test.c
static void* readfile(const char* path, size_t maxlen, size_t* len)
{
FILE* file;
file = fopen(path, "r");
if (file == NULL) {
fprintf(stderr, "Failed to open %s: %s\n", path, strerror(errno));
return NULL;
}
char* data = calloc(maxlen, 1);
size_t offset = 0;
size_t rv;
while ((rv = fread(data + offset, 1, maxlen - offset, file)) > 0) {
offset += rv;
}
if (ferror(file)) {
fprintf(stderr, "Failed to read %s: %s\n", path, strerror(errno));
fclose(file);
free(data);
return NULL;
}
if (!feof(file)) {
fprintf(stderr, "Failed to read %s because it is too large (max %u bytes)\n", path, (unsigned)maxlen);
fclose(file);
free(data);
return NULL;
}
fclose(file);
if (len) {
*len = offset;
}
return (void*)data;
}
int main(void) {
bool jit = false;
struct ubpf_vm* vm = ubpf_create();
// read bpf program bytecode
uint32_t code_len;
char* errmsg;
void* code = readfile("double.bpf.o", 65536, &code_len);
if (ubpf_load_elf(vm, code, code_len, &errmsg)) {
fprintf(stderr, "Failed to load program: %s\n", errmsg);
return -1;
}
const size_t mem_len = 1024;
char mem[mem_len];
*(int*)mem = 42;
uint64_t result;
if (jit) {
// jit
printf("jit\n");
ubpf_jit_fn fn = ubpf_compile(vm, &errmsg);
if (fn == NULL) {
fprintf(stderr, "Failed to compile program: %s\n", errmsg);
return -1;
}
result = fn(mem, mem_len);
printf("result: %lu\n", result);
} else {
// not jit
printf("not jit\n");
if (ubpf_exec(vm, mem, mem_len, &result)) {
fprintf(stderr, "Failed to execute program: %s\n", ubpf_error(vm));
return -1;
}
printf("result: %lu\n", result);
}
// double.bpf.c doubles mem
assert(result == 84);
ubpf_destroy(vm);
return 0;
}
@cs-qyzhang
Copy link
Author

sudo apt install libboost-all-dev
git clone https://github.com/iovisor/ubpf.git
cd ubpf
git submodule update --recursive
cmake -S . -B build -DUBPF_ENABLE_TESTS=true
cmake --build build --config Debug
cd build
vim test_bpf.c # copy test_bpf.c
vim double.bpf.c # copy double.bpf.c
clang -target bpf -I/usr/include/x86_64-linux-gnu -O2 -g -c double.bpf.c -o double.bpf.o
gcc -o test_bpf -I./vm test_bpf.c -L./lib -lubpf
./test_bpf

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment