mirror of https://github.com/torvalds/linux.git
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: 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>
This commit is contained in:
parent
10843e1492
commit
f6ceec6434
|
|
@ -4204,6 +4204,9 @@ struct sk_buff *__skb_recv_datagram(struct sock *sk,
|
||||||
struct sk_buff_head *sk_queue,
|
struct sk_buff_head *sk_queue,
|
||||||
unsigned int flags, int *off, int *err);
|
unsigned int flags, int *off, int *err);
|
||||||
struct sk_buff *skb_recv_datagram(struct sock *sk, unsigned int flags, 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,
|
__poll_t datagram_poll(struct file *file, struct socket *sock,
|
||||||
struct poll_table_struct *wait);
|
struct poll_table_struct *wait);
|
||||||
int skb_copy_datagram_iter(const struct sk_buff *from, int offset,
|
int skb_copy_datagram_iter(const struct sk_buff *from, int offset,
|
||||||
|
|
|
||||||
|
|
@ -920,21 +920,22 @@ int skb_copy_and_csum_datagram_msg(struct sk_buff *skb,
|
||||||
EXPORT_SYMBOL(skb_copy_and_csum_datagram_msg);
|
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
|
* @file: file struct
|
||||||
* @sock: socket
|
* @sock: socket
|
||||||
* @wait: poll table
|
* @wait: poll table
|
||||||
|
* @rcv_queue: receive queue to poll
|
||||||
*
|
*
|
||||||
* Datagram poll: Again totally generic. This also handles
|
* Performs polling on the given receive queue, handling shutdown, error,
|
||||||
* sequenced packet sockets providing the socket receive queue
|
* and connection state. This is useful for protocols that deliver
|
||||||
* is only ever holding data ready to receive.
|
* userspace-bound packets through a custom queue instead of
|
||||||
|
* sk->sk_receive_queue.
|
||||||
*
|
*
|
||||||
* Note: when you *don't* use this routine for this protocol,
|
* Return: poll bitmask indicating the socket's current state
|
||||||
* and you use a different write policy from sock_writeable()
|
|
||||||
* then please supply your own write_space callback.
|
|
||||||
*/
|
*/
|
||||||
__poll_t datagram_poll(struct file *file, struct socket *sock,
|
__poll_t datagram_poll_queue(struct file *file, struct socket *sock,
|
||||||
poll_table *wait)
|
poll_table *wait, struct sk_buff_head *rcv_queue)
|
||||||
{
|
{
|
||||||
struct sock *sk = sock->sk;
|
struct sock *sk = sock->sk;
|
||||||
__poll_t mask;
|
__poll_t mask;
|
||||||
|
|
@ -956,7 +957,7 @@ __poll_t datagram_poll(struct file *file, struct socket *sock,
|
||||||
mask |= EPOLLHUP;
|
mask |= EPOLLHUP;
|
||||||
|
|
||||||
/* readable? */
|
/* readable? */
|
||||||
if (!skb_queue_empty_lockless(&sk->sk_receive_queue))
|
if (!skb_queue_empty_lockless(rcv_queue))
|
||||||
mask |= EPOLLIN | EPOLLRDNORM;
|
mask |= EPOLLIN | EPOLLRDNORM;
|
||||||
|
|
||||||
/* Connection-based need to check for termination and startup */
|
/* 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;
|
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);
|
EXPORT_SYMBOL(datagram_poll);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue