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. */