On Thu, 2024-01-18 at 19:58 +0800, Shung-Hsi Yu wrote: > Hi, > > Compilation of lsm_cgroup.c will fail if the vmlinux.h comes from a > kernel that does _not_ have CONFIG_PACKET=y. The reason is that the > definition of struct sockaddr_ll is not present in vmlinux.h and the > compiler will complain that is has an incomplete type. > > CLNG-BPF [test_maps] lsm_cgroup.bpf.o > progs/lsm_cgroup.c:105:21: error: variable has incomplete type 'struct sockaddr_ll' > 105 | struct sockaddr_ll sa = {}; > | ^ > progs/lsm_cgroup.c:105:9: note: forward declaration of 'struct sockaddr_ll' > 105 | struct sockaddr_ll sa = {}; > | ^ > 1 error generated. > > While including linux/if_packet.h somehow made the compilation works for > me, IIUC this isn't a proper solution because vmlinux.h and kernel > headers should not be used at the same time (and would lead to > redefinition error when the kernel is built with CONFIG_PACKET=y, e.g. > on BPF CI). > > What would be the suggested way to work around this? > > Thanks, > Shung-Hsi Hi Shung-Hsi, One option is to use CO-RE, e.g. as at the bottom of this email (not sure if people would agree with me). But that would not produce usable test anyways, as load would fail with unresolved CO-RE relocation. But what is your final goal? As far as I understand, selftests are supposed to be built and run using specific configuration, here is how config for x86 CI is prepared: ./scripts/kconfig/merge_config.sh \ ./tools/testing/selftests/bpf/config \ ./tools/testing/selftests/bpf/config.vm \ ./tools/testing/selftests/bpf/config.x86_64 (root is kernel source). I'm not sure if other configurations are supposed to be supported. Thanks, Eduard --- diff --git a/tools/testing/selftests/bpf/progs/lsm_cgroup.c b/tools/testing/selftests/bpf/progs/lsm_cgroup.c index 02c11d16b692..8381e5a202c8 100644 --- a/tools/testing/selftests/bpf/progs/lsm_cgroup.c +++ b/tools/testing/selftests/bpf/progs/lsm_cgroup.c @@ -2,6 +2,7 @@ #include "vmlinux.h" #include "bpf_tracing_net.h" +#include <bpf/bpf_core_read.h> #include <bpf/bpf_helpers.h> #include <bpf/bpf_tracing.h> @@ -98,11 +99,15 @@ int BPF_PROG(socket_post_create2, struct socket *sock, int family, return real_create(sock, family, protocol); } +struct sockaddr_ll___local { + __be16 sll_protocol; +} __attribute__((preserve_access_index)); + static __always_inline int real_bind(struct socket *sock, struct sockaddr *address, int addrlen) { - struct sockaddr_ll sa = {}; + __u16 sll_protocol = 0; if (sock->sk->__sk_common.skc_family != AF_PACKET) return 1; @@ -110,8 +115,10 @@ static __always_inline int real_bind(struct socket *sock, if (sock->sk->sk_kern_sock) return 1; - bpf_probe_read_kernel(&sa, sizeof(sa), address); - if (sa.sll_protocol) + bpf_probe_read_kernel( + &sll_protocol, sizeof(sll_protocol), + (__u8*)address + bpf_core_field_offset(struct sockaddr_ll___local, sll_protocol)); + if (sll_protocol) return 0; /* EPERM */ /* Can access cgroup local storage. */