Skip to content

Commit efd7294

Browse files
ralfliciPaolo Abeni
authored andcommitted
ovpn: use datagram_poll_queue for socket readiness in TCP
openvpn TCP encapsulation uses a custom queue to deliver packets to userspace. Currently it relies on datagram_poll, which checks sk_receive_queue, leading to false readiness signals when that queue contains non-userspace packets. Switch ovpn_tcp_poll to use datagram_poll_queue with the peer's user_queue, ensuring poll only signals readiness when userspace data is actually available. Also refactor ovpn_tcp_poll in order to enforce the assumption we can make on the lifetime of ovpn_sock and peer. Fixes: 11851cb ("ovpn: implement TCP transport") Signed-off-by: Antonio Quartulli <antonio@openvpn.net> Signed-off-by: Ralf Lici <ralf@mandelbit.com> Reviewed-by: Sabrina Dubroca <sd@queasysnail.net> Link: https://patch.msgid.link/20251021100942.195010-4-ralf@mandelbit.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
1 parent 0fc3e32 commit efd7294

1 file changed

Lines changed: 22 additions & 4 deletions

File tree

drivers/net/ovpn/tcp.c

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -560,16 +560,34 @@ static void ovpn_tcp_close(struct sock *sk, long timeout)
560560
static __poll_t ovpn_tcp_poll(struct file *file, struct socket *sock,
561561
poll_table *wait)
562562
{
563-
__poll_t mask = datagram_poll(file, sock, wait);
563+
struct sk_buff_head *queue = &sock->sk->sk_receive_queue;
564564
struct ovpn_socket *ovpn_sock;
565+
struct ovpn_peer *peer = NULL;
566+
__poll_t mask;
565567

566568
rcu_read_lock();
567569
ovpn_sock = rcu_dereference_sk_user_data(sock->sk);
568-
if (ovpn_sock && ovpn_sock->peer &&
569-
!skb_queue_empty(&ovpn_sock->peer->tcp.user_queue))
570-
mask |= EPOLLIN | EPOLLRDNORM;
570+
/* if we landed in this callback, we expect to have a
571+
* meaningful state. The ovpn_socket lifecycle would
572+
* prevent it otherwise.
573+
*/
574+
if (WARN(!ovpn_sock || !ovpn_sock->peer,
575+
"ovpn: null state in ovpn_tcp_poll!")) {
576+
rcu_read_unlock();
577+
return 0;
578+
}
579+
580+
if (ovpn_peer_hold(ovpn_sock->peer)) {
581+
peer = ovpn_sock->peer;
582+
queue = &peer->tcp.user_queue;
583+
}
571584
rcu_read_unlock();
572585

586+
mask = datagram_poll_queue(file, sock, wait, queue);
587+
588+
if (peer)
589+
ovpn_peer_put(peer);
590+
573591
return mask;
574592
}
575593

0 commit comments

Comments
 (0)