ubpf
ubpf copied to clipboard
What is the simplest `prog.c` can be passed to `vm/test`?
Hello,
I'd like to play with this tool, however, I'm not quite sure how to get started with it.
Is there a simple example to get started with? Like a simple prog.c
?
Thanks, Alireza
Hi! What are you planning to do with ubpf ?
Example for prog.c
unsigned long int prog(char *addr) {
if (addr)
return 0;
return 1;
}
Compile and run
$ clang -c prog.c -target bpf -o prog
$ vm/test prog
0x1
$ vm/test -m prog prog # addr will have the content of prog
0x0
Thank you @carverdamien
I actually looked at Oko, and I realized that there are a couple of things not available in the uBPF, for example, maps. Although Oko has been built on top of uBPF.
I'd like to write complex eBPF functionalities using uBPF, isn't it possible? Imagine the following scenario for a single packet.
Wire -> NIC -> Kernel -> Userspace - Run a chain of BPF programs on the packet via uBPF -> Kernel -> NIC -> Wire
I'm also wondering what libraries I'm allowed or able to include in the uBPF programs?
You can call external functions in a bpf program but they must be registered first. register_functions
Hi @carverdamien
I'm wondering why I couldn't call for example sqrti
function in our simple prog.c file.
Here is what I did.
unsigned long int prog(char *addr) {
sqrti(16); // here I called the registered function.
if (addr)
return 0;
return 1;
}
Here is the warning generated. warning: implicit declaration of function 'sqrti' is invalid in C99 [-Wimplicit-function-declaration] sqrti(16);
When I run the program I get the following:
Failed to load code: bad relocation type 10
Probably, I'm missing something obvious here.
Thanks, Alireza
Helper calls in BPF are encoded as a call to an integer, where the integer is the index of the registered function you want to call. I think it should look something like this in C:
static int (*sqrti)(int) = (void *)1; // 1 is the index of our registered sqrti
unsigned long int prog(char *addr) {
sqrti(16); // here I called the registered function.
if (addr)
return 0;
return 1;
}
Unfortunately, I haven't been able to compile this such that vm/test
is happy with it; it always results in Failed to load code: bad relocation type 1
.
Compile with -O2
root@cda22c35d683:~# cat prog.c
static int (*sqrti)(int) = (void *)3;
unsigned long int prog(char *addr) {
return sqrti(16);
}
root@cda22c35d683:~# cat prog.s
.text
.file "prog.c"
.globl prog # -- Begin function prog
.p2align 3
.type prog,@function
prog: # @prog
# %bb.0:
r1 = 16
call 3
r0 <<= 32
r0 s>>= 32
exit
.Lfunc_end0:
.size prog, .Lfunc_end0-prog
# -- End function
.addrsig
root@cda22c35d683:~# ./src/ubpf/vm/test -m prog prog
0x4
Hello again,
Thanks for your time.
I have gone through the same steps. However, I'm still having troubles with Failed to load code: bad relocation type 10
.
I also took a screenshot of my steps, which is similar to yours.
Isn't it a compiler version issue or something? Mine is "10.0.0"
You might be confusing prog
and prog.o
True, thank you :)
You are welcome ! :D
I actually looked at Oko, and I realized that there are a couple of things not available in the uBPF, for example, maps. Although Oko has been built on top of uBPF.
Oko author here :wave:
That's true, Oko supports additional features on top of ubpf, such as hash maps, arrays, and a simple verifier. I unfortunately never found the time to upstream all of those to ubpf :disappointed:
I'd like to write complex eBPF functionalities using uBPF, isn't it possible? Imagine the following scenario for a single packet. Wire -> NIC -> Kernel -> Userspace - Run a chain of BPF programs on the packet via uBPF -> Kernel -> NIC -> Wire
That is definitely possible. However, note that ubpf will only implement the actual uBPF loading and execution. To receive and send packets from userspace, you'll have to use something else, such as DPDK or Linux's AK_PACKET API.
+1 to @pchaigno upstreaming those Oko changes back into this repo ;-)!