Commit 73d0280f authored by Andrii Nakryiko's avatar Andrii Nakryiko Committed by Daniel Borkmann
Browse files

libbpf: Improve usability of field-based CO-RE helpers



Allow to specify field reference in two ways:

  - if user has variable of necessary type, they can use variable-based
    reference (my_var.my_field or my_var_ptr->my_field). This was the
    only supported syntax up till now.
  - now, bpf_core_field_exists() and bpf_core_field_size() support also
    specifying field in a fashion similar to offsetof() macro, by
    specifying type of the containing struct/union separately and field
    name separately: bpf_core_field_exists(struct my_type, my_field).
    This forms is quite often more convenient in practice and it matches
    type-based CO-RE helpers that support specifying type by its name
    without requiring any variables.

Signed-off-by: default avatarAndrii Nakryiko <andrii@kernel.org>
Signed-off-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
Link: https://lore.kernel.org/bpf/20220509004148.1801791-4-andrii@kernel.org
parent 8e2f618e
Loading
Loading
Loading
Loading
+21 −4
Original line number Diff line number Diff line
@@ -110,21 +110,38 @@ enum bpf_enum_value_kind {
	val;								      \
})

#define ___bpf_field_ref1(field)	(field)
#define ___bpf_field_ref2(type, field)	(((typeof(type) *)0)->field)
#define ___bpf_field_ref(args...)					    \
	___bpf_apply(___bpf_field_ref, ___bpf_narg(args))(args)

/*
 * Convenience macro to check that field actually exists in target kernel's.
 * Returns:
 *    1, if matching field is present in target kernel;
 *    0, if no matching field found.
 *
 * Supports two forms:
 *   - field reference through variable access:
 *     bpf_core_field_exists(p->my_field);
 *   - field reference through type and field names:
 *     bpf_core_field_exists(struct my_type, my_field).
 */
#define bpf_core_field_exists(field)					    \
	__builtin_preserve_field_info(field, BPF_FIELD_EXISTS)
#define bpf_core_field_exists(field...)					    \
	__builtin_preserve_field_info(___bpf_field_ref(field), BPF_FIELD_EXISTS)

/*
 * Convenience macro to get the byte size of a field. Works for integers,
 * struct/unions, pointers, arrays, and enums.
 *
 * Supports two forms:
 *   - field reference through variable access:
 *     bpf_core_field_size(p->my_field);
 *   - field reference through type and field names:
 *     bpf_core_field_size(struct my_type, my_field).
 */
#define bpf_core_field_size(field)					    \
	__builtin_preserve_field_info(field, BPF_FIELD_BYTE_SIZE)
#define bpf_core_field_size(field...)					    \
	__builtin_preserve_field_info(___bpf_field_ref(field), BPF_FIELD_BYTE_SIZE)

/*
 * Convenience macro to get BTF type ID of a specified type, using a local BTF