Add a new helper "struct bpf_sock *bpf_get_listener_sock(struct bpf_sock *sk)" which returns a bpf_sock in TCP_LISTEN state. It will trace back to the listener sk from a request_sock if possible. It returns NULL for all other cases. No reference is taken because the helper ensures the sk is in SOCK_RCU_FREE (where the TCP_LISTEN sock should be in). Hence, bpf_sk_release() is unnecessary and the verifier does not allow bpf_sk_release(listen_sk) to be called either. The following is also allowed because the bpf_prog is run under rcu_read_lock(): sk = bpf_sk_lookup_tcp(); /* if (!sk) { ... } */ listen_sk = bpf_get_listener_sock(sk); /* if (!listen_sk) { ... } */ bpf_sk_release(sk); src_port = listen_sk->src_port; /* Allowed */
Showing the changes to include/uapi/linux (1 of 2 files). Show all
Unified · Split
| @@ -2366,6 +2366,14 @@ union bpf_attr { · 2365 unmodified lines | |||
| 2366 | * current value is ect (ECN capable). Works with IPv6 and IPv4. | 2366 | * current value is ect (ECN capable). Works with IPv6 and IPv4. |
| 2367 | * Return | 2367 | * Return |
| 2368 | * 1 if set, 0 if not set. | 2368 | * 1 if set, 0 if not set. |
| 2369 | * | ||
| 2370 | * struct bpf_sock *bpf_get_listener_sock(struct bpf_sock *sk) | ||
| 2371 | * Description | ||
| 2372 | * Return a **struct bpf_sock** pointer in TCP_LISTEN state. | ||
| 2373 | * bpf_sk_release() is unnecessary and not allowed. | ||
| 2374 | * Return | ||
| 2375 | * A **struct bpf_sock** pointer on success, or NULL in | ||
| 2376 | * case of failure. | ||
| 2369 | */ | 2377 | */ |
| 2370 | #define __BPF_FUNC_MAPPER(FN) \ | 2378 | #define __BPF_FUNC_MAPPER(FN) \ |
| 2371 | FN(unspec), \ | 2379 | FN(unspec), \ |
| @@ -2465,7 +2473,8 @@ union bpf_attr { · 93 unmodified lines | |||
| 2465 | FN(spin_unlock), \ | 2473 | FN(spin_unlock), \ |
| 2466 | FN(sk_fullsock), \ | 2474 | FN(sk_fullsock), \ |
| 2467 | FN(tcp_sock), \ | 2475 | FN(tcp_sock), \ |
| 2468 | FN(skb_ecn_set_ce), | 2476 | FN(skb_ecn_set_ce), \ |
| 2477 | FN(get_listener_sock), | ||
| 2469 | 2478 | ||
| 2470 | /* integer value in 'imm' field of BPF_CALL instruction selects which helper | 2479 | /* integer value in 'imm' field of BPF_CALL instruction selects which helper |
| 2471 | * function eBPF program intends to call | 2480 | * function eBPF program intends to call |