]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
net: datagram: introduce datagram_poll_queue for custom receive queues
authorRalf Lici <ralf@mandelbit.com>
Tue, 21 Oct 2025 10:09:40 +0000 (12:09 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 29 Oct 2025 13:10:20 +0000 (14:10 +0100)
[ Upstream commit f6ceec6434b5efff62cecbaa2ff74fc29b96c0c6 ]

Some protocols using TCP encapsulation (e.g., espintcp, openvpn) deliver
userspace-bound packets through a custom skb queue rather than the
standard sk_receive_queue.

Introduce datagram_poll_queue that accepts an explicit receive queue,
and convert datagram_poll into a wrapper around datagram_poll_queue.
This allows protocols with custom skb queues to reuse the core polling
logic without relying on sk_receive_queue.

Cc: Sabrina Dubroca <sd@queasysnail.net>
Cc: Antonio Quartulli <antonio@openvpn.net>
Signed-off-by: Ralf Lici <ralf@mandelbit.com>
Reviewed-by: Sabrina Dubroca <sd@queasysnail.net>
Reviewed-by: Antonio Quartulli <antonio@openvpn.net>
Link: https://patch.msgid.link/20251021100942.195010-2-ralf@mandelbit.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Stable-dep-of: efd729408bc7 ("ovpn: use datagram_poll_queue for socket readiness in TCP")
Signed-off-by: Sasha Levin <sashal@kernel.org>
include/linux/skbuff.h
net/core/datagram.c

index fa633657e4c068f2484086126fe25d50674e21cc..ad66110b43ccac867b0c27a54a493c2deeed6cd3 100644 (file)
@@ -4157,6 +4157,9 @@ struct sk_buff *__skb_recv_datagram(struct sock *sk,
                                    struct sk_buff_head *sk_queue,
                                    unsigned int flags, int *off, int *err);
 struct sk_buff *skb_recv_datagram(struct sock *sk, unsigned int flags, int *err);
+__poll_t datagram_poll_queue(struct file *file, struct socket *sock,
+                            struct poll_table_struct *wait,
+                            struct sk_buff_head *rcv_queue);
 __poll_t datagram_poll(struct file *file, struct socket *sock,
                           struct poll_table_struct *wait);
 int skb_copy_datagram_iter(const struct sk_buff *from, int offset,
index f474b9b120f984c9e013abfbc4b68984b8a3a6d8..8b328879f8d251a47a6be7efd6412c55b9d4a03e 100644 (file)
@@ -920,21 +920,22 @@ fault:
 EXPORT_SYMBOL(skb_copy_and_csum_datagram_msg);
 
 /**
- *     datagram_poll - generic datagram poll
+ *     datagram_poll_queue - same as datagram_poll, but on a specific receive
+ *             queue
  *     @file: file struct
  *     @sock: socket
  *     @wait: poll table
+ *     @rcv_queue: receive queue to poll
  *
- *     Datagram poll: Again totally generic. This also handles
- *     sequenced packet sockets providing the socket receive queue
- *     is only ever holding data ready to receive.
+ *     Performs polling on the given receive queue, handling shutdown, error,
+ *     and connection state. This is useful for protocols that deliver
+ *     userspace-bound packets through a custom queue instead of
+ *     sk->sk_receive_queue.
  *
- *     Note: when you *don't* use this routine for this protocol,
- *     and you use a different write policy from sock_writeable()
- *     then please supply your own write_space callback.
+ *     Return: poll bitmask indicating the socket's current state
  */
-__poll_t datagram_poll(struct file *file, struct socket *sock,
-                          poll_table *wait)
+__poll_t datagram_poll_queue(struct file *file, struct socket *sock,
+                            poll_table *wait, struct sk_buff_head *rcv_queue)
 {
        struct sock *sk = sock->sk;
        __poll_t mask;
@@ -956,7 +957,7 @@ __poll_t datagram_poll(struct file *file, struct socket *sock,
                mask |= EPOLLHUP;
 
        /* readable? */
-       if (!skb_queue_empty_lockless(&sk->sk_receive_queue))
+       if (!skb_queue_empty_lockless(rcv_queue))
                mask |= EPOLLIN | EPOLLRDNORM;
 
        /* Connection-based need to check for termination and startup */
@@ -978,4 +979,27 @@ __poll_t datagram_poll(struct file *file, struct socket *sock,
 
        return mask;
 }
+EXPORT_SYMBOL(datagram_poll_queue);
+
+/**
+ *     datagram_poll - generic datagram poll
+ *     @file: file struct
+ *     @sock: socket
+ *     @wait: poll table
+ *
+ *     Datagram poll: Again totally generic. This also handles
+ *     sequenced packet sockets providing the socket receive queue
+ *     is only ever holding data ready to receive.
+ *
+ *     Note: when you *don't* use this routine for this protocol,
+ *     and you use a different write policy from sock_writeable()
+ *     then please supply your own write_space callback.
+ *
+ *     Return: poll bitmask indicating the socket's current state
+ */
+__poll_t datagram_poll(struct file *file, struct socket *sock, poll_table *wait)
+{
+       return datagram_poll_queue(file, sock, wait,
+                                  &sock->sk->sk_receive_queue);
+}
 EXPORT_SYMBOL(datagram_poll);