Currently, udp_abort() invokes __udp_disconnect() which clears out socket fields like inet_daddr and inet_dport. This makes fields like dst_ip4, dst_ip6, and dst_port useless inside cgroup/sock_release BPF hooks following an abort on a connected UDP socket, since they'll always equal zero. This differs from the behavior for TCP sockets where a cgroup/sock_release hook will see the address and port that the socket was connected to at the time it was aborted. This causes issues in Cilium where a sock_release hook is used to perform map maintenance when sockets are released, since Cilium actively destroys connected UDP sockets in some cases. Make the behavior consistent between TCP and UDP sockets by not clearing out these fields in udp_abort(). Instead, just unhash the socket, mark its state as TCP_CLOSE, and preserve the state of the other fields. Fixes: f5836749c9c0 ("bpf: Add BPF_CGROUP_INET_SOCK_RELEASE hook") Reported-by: Yusuke Suzuki Signed-off-by: Jordan Rife --- net/ipv4/udp.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index b96e47f1c8a2..01a0a0fbcd56 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c @@ -3247,7 +3247,9 @@ int udp_abort(struct sock *sk, int err) sk->sk_err = err; sk_error_report(sk); - __udp_disconnect(sk, 0); + sk->sk_state = TCP_CLOSE; + sk->sk_prot->unhash(sk); + sk_dst_reset(sk); out: if (!has_current_bpf_ctx()) -- 2.53.0.414.gf7e9f6c205-goog