Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

What is the simplest prog.c can be passed to vm/test? #54

Open
sarsanaee opened this issue Feb 1, 2021 · 12 comments
Open

What is the simplest prog.c can be passed to vm/test? #54

sarsanaee opened this issue Feb 1, 2021 · 12 comments

Comments

@sarsanaee
Copy link

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

@carverdamien
Copy link

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

@sarsanaee
Copy link
Author

sarsanaee commented Feb 2, 2021

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?

@carverdamien
Copy link

You can call external functions in a bpf program but they must be registered first. register_functions

@sarsanaee
Copy link
Author

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

@jpsamaroo
Copy link

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.

@carverdamien
Copy link

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

@sarsanaee
Copy link
Author

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.

image

Isn't it a compiler version issue or something? Mine is "10.0.0"

@carverdamien
Copy link

You might be confusing prog and prog.o

@sarsanaee
Copy link
Author

True, thank you :)

@carverdamien
Copy link

You are welcome ! :D

@pchaigno
Copy link
Collaborator

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 👋

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 😞

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.

@sbates130272
Copy link

+1 to @pchaigno upstreaming those Oko changes back into this repo ;-)!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants