mirror of
https://github.com/xdp-project/bpf-examples.git
synced 2024-05-06 15:54:53 +00:00
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:
@@ -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
|
||||
|
||||
|
Reference in New Issue
Block a user