## Understanding `vmlinux.h` in BPF

The `vmlinux.h` header is crucial for building BPF (Berkeley Packet Filter) programs that inspect core kernel data structures.


### What is `vmlinux.h`?

`vmlinux.h` is a C header file that contains the layout of internal kernel data structures. This allows a BPF program to access internal information from the kernel. BPF programs that inspect internel kernel data structures should utilize a feature called CO-RE (Compile Once - Run Everywhere). In essence, CO-RE allows BPF programs to work safely across different kernel versions without needing to be recompiled for each one.

NOTE: While a BPF program doesn't need a `vmlinux.h` file that perfectly matches the target kernel, it's important to regenerate it in some cases. For instance, if the program makes use of a new field added to a structure, you must create a new vmlinux.h to access that new field.

### How is `vmlinux.h` Generated?

A `vmlinux.h` file is created from a `vmlinux` file (the raw, uncompressed kernel image with BTF info) using the `bpftool` utility. The command for this is:

```sh
bpftool btf dump file /path/to/vmlinux format c > vmlinux.h
```

### Architecture Considerations on Android

A BPF program must be compiled with a vmlinux.h file that matches the architecture of the target kernel.

 + *`64-bit` Systems*: On `64-bit` Android systems (either `arm64` or `x86_64`), this is straightforward. The `64-bit` userspace (where the application runs) matches the `64-bit` kernel.
 + *`32-bit` Systems*: This is more complex on devices with a `32-bit` Android userspace (arm or x86). At the time the BPF program is built, it's impossible to know if the device's kernel will be `32-bit` or `64-bit`. Because of this uncertainty, the system defaults to assuming a `32-bit` userspace running on a `64-bit` kernel. As a result, BPF programs that rely on libbpf will be disabled at runtime on systems that have a `32-bit` kernel.

### How to Generate vmlinux.h for New Kernels

When a new Android kernel version is released, a corresponding `vmlinux.h` can be generated by adding a new build rule to `system/bpf/include/vmlinux/Android.bp`.

You can do this by simply copying the existing rule for the latest kernel version and modifying it for the new one.
