mirror of
https://github.com/torvalds/linux.git
synced 2026-09-23 13:14:02 +02:00
bpf: Extract shared reqsk-to-listener upgrade
__bpf_sk_lookup() and bpf_sk_lookup() duplicate the same sk_to_full_sk() reqsk-to-listener upgrade. Extract it into a helper. Leave the currently unreachable WARN_ONCE as a defensive assert. No functional change. Signed-off-by: Michal Luczaj <mhal@rbox.co> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Reviewed-by: Emil Tsalapatis <emil@etsalapatis.com> Reviewed-by: Jakub Sitnicki <jakub@cloudflare.com> Link: https://lore.kernel.org/bpf/20260813-sockmap-lookup-get-ref-v1-1-31f5d55f44ac@rbox.co
This commit is contained in:
parent
d99bda7f01
commit
3c3d2c09ec
|
|
@ -7167,6 +7167,28 @@ __bpf_skc_lookup(struct sk_buff *skb, struct bpf_sock_tuple *tuple, u32 len,
|
|||
return sk;
|
||||
}
|
||||
|
||||
static struct sock *
|
||||
bpf_sk_lookup_full_sk(struct sock *sk)
|
||||
{
|
||||
struct sock *sk2 = sk_to_full_sk(sk);
|
||||
|
||||
/*
|
||||
* sk_to_full_sk() may return sk->rsk_listener, make sure the original
|
||||
* sk sock refcnt is decremented to prevent a request_sock leak.
|
||||
*/
|
||||
if (sk2 != sk) {
|
||||
sock_gen_put(sk);
|
||||
/* Ensure there is no need to bump sk2 refcnt. */
|
||||
if (unlikely(sk2 && !sock_flag(sk2, SOCK_RCU_FREE))) {
|
||||
WARN_ONCE(1, "Found non-RCU, unreferenced socket!");
|
||||
return NULL;
|
||||
}
|
||||
sk = sk2;
|
||||
}
|
||||
|
||||
return sk;
|
||||
}
|
||||
|
||||
static struct sock *
|
||||
__bpf_sk_lookup(struct sk_buff *skb, struct bpf_sock_tuple *tuple, u32 len,
|
||||
struct net *caller_net, u32 ifindex, u8 proto, u64 netns_id,
|
||||
|
|
@ -7175,24 +7197,8 @@ __bpf_sk_lookup(struct sk_buff *skb, struct bpf_sock_tuple *tuple, u32 len,
|
|||
struct sock *sk = __bpf_skc_lookup(skb, tuple, len, caller_net,
|
||||
ifindex, proto, netns_id, flags,
|
||||
sdif);
|
||||
|
||||
if (sk) {
|
||||
struct sock *sk2 = sk_to_full_sk(sk);
|
||||
|
||||
/* sk_to_full_sk() may return (sk)->rsk_listener, so make sure the original sk
|
||||
* sock refcnt is decremented to prevent a request_sock leak.
|
||||
*/
|
||||
if (sk2 != sk) {
|
||||
sock_gen_put(sk);
|
||||
/* Ensure there is no need to bump sk2 refcnt */
|
||||
if (unlikely(sk2 && !sock_flag(sk2, SOCK_RCU_FREE))) {
|
||||
WARN_ONCE(1, "Found non-RCU, unreferenced socket!");
|
||||
return NULL;
|
||||
}
|
||||
sk = sk2;
|
||||
}
|
||||
}
|
||||
|
||||
if (sk)
|
||||
sk = bpf_sk_lookup_full_sk(sk);
|
||||
return sk;
|
||||
}
|
||||
|
||||
|
|
@ -7221,24 +7227,8 @@ bpf_sk_lookup(struct sk_buff *skb, struct bpf_sock_tuple *tuple, u32 len,
|
|||
{
|
||||
struct sock *sk = bpf_skc_lookup(skb, tuple, len, proto, netns_id,
|
||||
flags);
|
||||
|
||||
if (sk) {
|
||||
struct sock *sk2 = sk_to_full_sk(sk);
|
||||
|
||||
/* sk_to_full_sk() may return (sk)->rsk_listener, so make sure the original sk
|
||||
* sock refcnt is decremented to prevent a request_sock leak.
|
||||
*/
|
||||
if (sk2 != sk) {
|
||||
sock_gen_put(sk);
|
||||
/* Ensure there is no need to bump sk2 refcnt */
|
||||
if (unlikely(sk2 && !sock_flag(sk2, SOCK_RCU_FREE))) {
|
||||
WARN_ONCE(1, "Found non-RCU, unreferenced socket!");
|
||||
return NULL;
|
||||
}
|
||||
sk = sk2;
|
||||
}
|
||||
}
|
||||
|
||||
if (sk)
|
||||
sk = bpf_sk_lookup_full_sk(sk);
|
||||
return sk;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user