On 12/04/2023 11:45, Florian Westphal wrote: > Quentin Deslandes <qde@xxxxxxxx> wrote: >> On 05/04/2023 18:11, Florian Westphal wrote: >>> Add minimal support to hook bpf programs to netfilter hooks, e.g. >>> PREROUTING or FORWARD. >>> >>> For this the most relevant parts for registering a netfilter >>> hook via the in-kernel api are exposed to userspace via bpf_link. >>> >>> The new program type is 'tracing style', i.e. there is no context >>> access rewrite done by verifier, the function argument (struct bpf_nf_ctx) >>> isn't stable. >>> There is no support for direct packet access, dynptr api should be used >>> instead. >> >> Does this mean the verifier will reject any program accessing ctx->skb >> (e.g. ctx->skb + X)? > > Do you mean access to ctx->skb->data + X? If so, yes, that won't work. > > Otherwise, then no, it just means that programs might have to be recompiled > if they lack needed relocation information, but only if bpf_nf_ctx structure is > changed. > > Initial version used "__sk_buff *skb", like e.g. clsact. I was told > to not do that and expose the real kernel-side structure instead and to > not bother with direct packet access (skb->data access) support. > That's exactly what I meant, thanks. >>> #include "vmlinux.h" >>> extern int bpf_dynptr_from_skb(struct __sk_buff *skb, __u64 flags, >>> struct bpf_dynptr *ptr__uninit) __ksym; >>> extern void *bpf_dynptr_slice(const struct bpf_dynptr *ptr, uint32_t offset, >>> void *buffer, uint32_t buffer__sz) __ksym; >>> SEC("netfilter") >>> int nf_test(struct bpf_nf_ctx *ctx) >>> { >>> struct nf_hook_state *state = ctx->state; >>> struct sk_buff *skb = ctx->skb; > > ctx->skb is dereferenced... > >>> if (bpf_dynptr_from_skb(skb, 0, &ptr)) >>> return NF_DROP; > > ... dynptr is created ... > >>> iph = bpf_dynptr_slice(&ptr, 0, &_iph, sizeof(_iph)); >>> if (!iph) >>> return NF_DROP; >>> th = bpf_dynptr_slice(&ptr, iph->ihl << 2, &_th, sizeof(_th)); > > ip header access.