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.
Showing the changes to tools/include/uapi/linux (1 of 8 files). Show all
Unified · Split
| @@ -4198,9 +4198,6 @@ union bpf_attr { · 4197 unmodified lines | |||
| 4198 | * **-EOPNOTSUPP** if the operation is not supported, for example | 4198 | * **-EOPNOTSUPP** if the operation is not supported, for example |
| 4199 | * a call from outside of TC ingress. | 4199 | * a call from outside of TC ingress. |
| 4200 | * | 4200 | * |
| 4201 | * **-ESOCKTNOSUPPORT** if the socket type is not supported | ||
| 4202 | * (reuseport). | ||
| 4203 | * | ||
| 4204 | * long bpf_sk_assign(struct bpf_sk_lookup *ctx, struct bpf_sock *sk, u64 flags) | 4201 | * long bpf_sk_assign(struct bpf_sk_lookup *ctx, struct bpf_sock *sk, u64 flags) |
| 4205 | * Description | 4202 | * Description |
| 4206 | * Helper is overloaded depending on BPF program type. This | 4203 | * Helper is overloaded depending on BPF program type. This |