mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/
synced 2026-10-18 19:12:56 +00:00
Currently the bpf_sk_assign helper in tc BPF context refuses SO_REUSEPORT
sockets. This means we can't use the helper to steer traffic to Envoy,
which configures SO_REUSEPORT on its sockets. In turn, we're blocked
from removing TPROXY from our setup.
The reason that bpf_sk_assign refuses such sockets is that the
bpf_sk_lookup helpers don't execute SK_REUSEPORT programs. Instead,
one of the reuseport sockets is selected by hash. This could cause
dispatch to the "wrong" socket:
sk = bpf_sk_lookup_tcp(...) // select SO_REUSEPORT by hash
bpf_sk_assign(skb, sk) // SK_REUSEPORT wasn't executed
Fixing this isn't as simple as invoking SK_REUSEPORT from the lookup
helpers unfortunately. In the tc context, L2 headers are at the start
of the skb, while SK_REUSEPORT expects L3 headers instead.
Instead, we execute the SK_REUSEPORT program when the assigned socket
is pulled out of the skb, further up the stack. This creates some
trickiness with regards to refcounting as bpf_sk_assign will put both
refcounted and RCU freed sockets in skb->sk. reuseport sockets are RCU
freed. We can infer that the sk_assigned socket is RCU freed if the
reuseport lookup succeeds, but convincing yourself of this fact isn't
straight forward. Therefore we defensively check refcounting on the
sk_assign sock even though it's probably not required in practice.
Fixes:
|
History
|
|
|---|---|---|
| .. | ||
| tc_act | ||
| bpf.h | ||
| bpf_common.h | ||
| bpf_perf_event.h | ||
| btf.h | ||
| const.h | ||
| erspan.h | ||
| ethtool.h | ||
| fadvise.h | ||
| fcntl.h | ||
| filter.h | ||
| fs.h | ||
| fscrypt.h | ||
| hw_breakpoint.h | ||
| if_link.h | ||
| if_tun.h | ||
| if_xdp.h | ||
| in.h | ||
| kcmp.h | ||
| kvm.h | ||
| mman.h | ||
| mount.h | ||
| netdev.h | ||
| netlink.h | ||
| openat2.h | ||
| perf_event.h | ||
| pkt_cls.h | ||
| pkt_sched.h | ||
| prctl.h | ||
| sched.h | ||
| seg6.h | ||
| seg6_local.h | ||
| stat.h | ||
| stddef.h | ||
| tcp.h | ||
| tls.h | ||
| types.h | ||
| usbdevice_fs.h | ||
| vhost.h | ||