AF_XDP-interaction: README: Explaning XDP-hints via local BTF info

Signed-off-by: Jesper Dangaard Brouer <brouer@redhat.com>
This commit is contained in:
Jesper Dangaard Brouer
2021-11-16 19:45:43 +01:00
parent ae4f6a5846
commit e9ec65d667

View File

@@ -1,7 +1,58 @@
#+Title: How to transfer info from XDP-prog to AF_XDP
This BPF-example show how use BTF to create a communication channel
between XDP-prog (running kernel-side) and AF_XDP user-space process.
between XDP BPF-prog (running kernel-side) and AF_XDP user-space
process, via XDP-hints in metadata area.
* XDP-hints via local BTF info
XDP-hints have been discussed as a facility where NIC drivers provide
information in the metadata area (located just before packet header
starts). There have been little progress on kernel drivers adding
XDP-hints, as end-users are unsure how to decode and consume the
information (chicken-and-egg problem).
In this example we let the BPF-object file define and contain the
BTF-info about the XDP-hints data-structures. Thus, no kernel or
driver changes are needed as the BTF type-definitions are *locally
defined*. And XDP-hints are used as communication channel between XDP
BPF-prog and AF_XDP userspace program.
The API for decoding the BTF data-structures have been added to
seperate files (in [[file:lib_xsk_extend.c]] and [[file:lib_xsk_extend.h]]) to
make this reusable for other projects, with the goal of getting this
included in libbpf or libxdp. The API takes an =struct btf= pointer
as input argument when searching for a struct-name. This BTF pointer
is obtained from opening the BPF-object ELF file, but it could also
come from the kernel (e.g via =btf__load_vmlinux_btf()=) and even from
a kernel module (e.g. via =btf__load_module_btf()=). See other
[[https://github.com/xdp-project/bpf-examples/blob/master/BTF-playground/btf_module_read.c][btf_module_read]] example howto do this.
The requirement for being a valid XDP-hints data-struct is that the
last member in the struct is named =btf_id= and have size 4 bytes
(32-bit). See C code example below. This =btf_id= member is used for
identifying what struct have been put into this metadata area. The
kernel-side BPF-prog stores the =btf_id= via using API
=bpf_core_type_id_local()= to obtain the ID. Userspace API reads the
=btf_id= via reading -4 bytes from packet header start, and can check
the ID against the IDs that was available via the =struct btf=
pointer.
#+begin_src C
struct xdp_hints_rx_time {
__u64 rx_ktime;
__u32 btf_id;
} __attribute__((aligned(4))) __attribute__((packed));
#+end_src
The location as the last member is because metadata area, located just
before packet header starts, can only grow "backwards" (via BPF-helper
=bpf_xdp_adjust_meta()=). To store a larger struct, the metadata is
grown by a larger negative offset. The BTF type-information knows the
size (and offsets) of all data-structures. Thus, we can deduce the
size of the metadata area, when knowing the =bpf_id=, which by placing
it as the last member is in a known location.
* AF_XDP documentation