HID-BPF metadata
Overview
The metadata of which device is a target for which bpf program is stored directly in the bpf resulting object file.
The syntax is the following:
HID_BPF_CONFIG(
HID_DEVICE(BBBB, GGGG, 0xVVVV, 0xPPPP)
);
Where:
BBBBis the bus value (in hexadecimal or by using the#defineinhid_bpf_helpers.h) (0x3orBUS_USBfor USB,0x18orBUS_I2Cfor I2C,0x5orBUS_BLUETOOTHfor Bluetooth, etc…)GGGGis the HID group as detected by HID (again, in hexadecimal or by using one of the#define)VVVVandPPPPare respectively the vendor ID and product ID (as inlsusb, so hexadecimal is easier too)
We can also add more than one match:
HID_BPF_CONFIG(
HID_DEVICE(BUS_USB, HID_GROUP_ANY, HID_VID_ANY, HID_PID_ANY),
HID_DEVICE(BUS_BLUETOOTH, HID_GROUP_ANY, HID_VID_ANY, HID_PID_ANY)
);
The above metadata will match on any USB or Bluetooth device.
How this is interpreted?
The idea of these metadata was borrowed from the libxdp project.
See the src/bpf/hid_bpf_helpers.h in the repository to see the actual macros.
The macro HID_BPF_CONFIG defines a new section in the ELF object that is later
parsed by BTF and our build.rs script when generating the hwdb. The actual C code
expands to something like this:
union {
/* HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, 0x1234, 0xabcd); */
struct { int (*bus)[0x3]; int (*group)[0x1]; int (*vid)[0x1234]; int (*pid)[0xabcd] } entry1;
/* HID_DEVICE(BUS_BLUETOOTH, HID_GROUP_GENERIC, 0x5678, 0xdead); */
struct { int (*bus)[0x5]; int (*group)[0x1]; int (*vid)[0x5678]; int (*pid)[0xdead] } entry2;
} _device_ids;
So this declares a global variable that is a union containing a set of structs. Note that the variable is never actually instantiated, this variable is only used for introspection via BTF.
The metadata information is then stored in the type of this global variable
(simplified version). During parsing we can iterate through the union and
inspect each field of the struct, including the size of the declared (pointer
to) array. In the above case: because the bus field is a pointer to an
array of size 3 we know the bus was 0x03 - USB.
See the src/bpf/hid_bpf_helpers.h in the repository to see the details.