Commit f6ceec64 authored by Ralf Lici's avatar Ralf Lici Committed by Paolo Abeni
Browse files

net: datagram: introduce datagram_poll_queue for custom receive queues



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: default avatarRalf Lici <ralf@mandelbit.com>
Reviewed-by: default avatarSabrina Dubroca <sd@queasysnail.net>
Reviewed-by: default avatarAntonio Quartulli <antonio@openvpn.net>
Link: https://patch.msgid.link/20251021100942.195010-2-ralf@mandelbit.com


Signed-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
parent 10843e14
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -4204,6 +4204,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,
+34 −10
Original line number Diff line number Diff line
@@ -920,21 +920,22 @@ int skb_copy_and_csum_datagram_msg(struct sk_buff *skb,
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);