1

Given a struct socket *sock I basically try to do the following:

struct sock {
    struct sock_common __sk_common;
} __attribute__((preserve_access_index));

struct socket {
    struct sock *sk; // sic! a pointer
} __attribute__((preserve_access_index));

struct net_device {
    int ifindex;
} __attribute__((preserve_access_index));

struct xdp_sock {
    struct sock sk;
    struct net_device *dev;
    u16 queue_id;
} __attribute__((preserve_access_index));

struct sock *sk = sock->sk;
if (sk->__sk_common.skc_family != AF_XDP) {
    return 0;
}
struct xdp_sock *xs = (struct xdp_sock *)sk;
struct net_device *dev = xs->dev;

Not totally unexpected, the eBPF verifier isn't exactly amused:

load program: permission denied: access beyond struct sock at off 776 size 8

A deeper look into bpf-helpers(7) as well as in libbpf's v1.1.0 bpf_helper_defs.h doesn't show any sign of any helper like bpf_skc_to_tcp_sock but instead for XDP sockets.

How do I correctly dynamically cast an "sk" into a struct xdp_sock * that is accepted by the verifier?

TheDiveO
  • 2,183
  • 2
  • 19
  • 38
  • Do you have a CO-RE struct definition for `struct xdp_sock`? What is it? – pchaigno Feb 20 '23 at 16:07
  • I've updated the snippet with the xdp_sock and net_device CO-RE "skeletons". – TheDiveO Feb 20 '23 at 16:23
  • I'm not super familiar with how the `preserve_access_index` in CO-RE work exactly, but could the fact that you didn't fully define `struct sock` cause issues when trying to compute the offset for `xdp_sock->dev`? – pchaigno Feb 20 '23 at 18:16
  • Yes and no; xdp_sock is containing sock as its "base type". The TCP sockets work similar, but for them are helpers. – TheDiveO Feb 20 '23 at 19:33

0 Answers0