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.
Unified · Split
| @@ -4204,6 +4204,9 @@ struct sk_buff *__skb_recv_datagram(struct sock *sk, · 4203 unmodified lines | |||
| 4204 | struct sk_buff_head *sk_queue, | 4204 | struct sk_buff_head *sk_queue, |
| 4205 | unsigned int flags, int *off, int *err); | 4205 | unsigned int flags, int *off, int *err); |
| 4206 | struct sk_buff *skb_recv_datagram(struct sock *sk, unsigned int flags, int *err); | 4206 | struct sk_buff *skb_recv_datagram(struct sock *sk, unsigned int flags, int *err); |
| 4207 | __poll_t datagram_poll_queue(struct file *file, struct socket *sock, | ||
| 4208 | struct poll_table_struct *wait, | ||
| 4209 | struct sk_buff_head *rcv_queue); | ||
| 4207 | __poll_t datagram_poll(struct file *file, struct socket *sock, | 4210 | __poll_t datagram_poll(struct file *file, struct socket *sock, |
| 4208 | struct poll_table_struct *wait); | 4211 | struct poll_table_struct *wait); |
| 4209 | int skb_copy_datagram_iter(const struct sk_buff *from, int offset, | 4212 | int skb_copy_datagram_iter(const struct sk_buff *from, int offset, |
| @@ -920,21 +920,22 @@ fault: · 919 unmodified lines | |||
| 920 | EXPORT_SYMBOL(skb_copy_and_csum_datagram_msg); | 920 | EXPORT_SYMBOL(skb_copy_and_csum_datagram_msg); |
| 921 | 921 | ||
| 922 | /** | 922 | /** |
| 923 | * datagram_poll - generic datagram poll | 923 | * datagram_poll_queue - same as datagram_poll, but on a specific receive |
| 924 | * queue | ||
| 924 | * @file: file struct | 925 | * @file: file struct |
| 925 | * @sock: socket | 926 | * @sock: socket |
| 926 | * @wait: poll table | 927 | * @wait: poll table |
| 928 | * @rcv_queue: receive queue to poll | ||
| 927 | * | 929 | * |
| 928 | * Datagram poll: Again totally generic. This also handles | 930 | * Performs polling on the given receive queue, handling shutdown, error, |
| 929 | * sequenced packet sockets providing the socket receive queue | 931 | * and connection state. This is useful for protocols that deliver |
| 930 | * is only ever holding data ready to receive. | 932 | * userspace-bound packets through a custom queue instead of |
| 933 | * sk->sk_receive_queue. | ||
| 931 | * | 934 | * |
| 932 | * Note: when you *don't* use this routine for this protocol, | 935 | * Return: poll bitmask indicating the socket's current state |
| 933 | * and you use a different write policy from sock_writeable() | ||
| 934 | * then please supply your own write_space callback. | ||
| 935 | */ | 936 | */ |
| 936 | __poll_t datagram_poll(struct file *file, struct socket *sock, | 937 | __poll_t datagram_poll_queue(struct file *file, struct socket *sock, |
| 937 | poll_table *wait) | 938 | poll_table *wait, struct sk_buff_head *rcv_queue) |
| 938 | { | 939 | { |
| 939 | struct sock *sk = sock->sk; | 940 | struct sock *sk = sock->sk; |
| 940 | __poll_t mask; | 941 | __poll_t mask; |
| @@ -956,7 +957,7 @@ __poll_t datagram_poll(struct file *file, struct socket *sock, · 15 unmodified lines | |||
| 956 | mask |= EPOLLHUP; | 957 | mask |= EPOLLHUP; |
| 957 | 958 | ||
| 958 | /* readable? */ | 959 | /* readable? */ |
| 959 | if (!skb_queue_empty_lockless(&sk->sk_receive_queue)) | 960 | if (!skb_queue_empty_lockless(rcv_queue)) |
| 960 | mask |= EPOLLIN | EPOLLRDNORM; | 961 | mask |= EPOLLIN | EPOLLRDNORM; |
| 961 | 962 | ||
| 962 | /* Connection-based need to check for termination and startup */ | 963 | /* Connection-based need to check for termination and startup */ |
| @@ -978,4 +979,27 @@ __poll_t datagram_poll(struct file *file, struct socket *sock, · 15 unmodified lines | |||
| 978 | 979 | ||
| 979 | return mask; | 980 | return mask; |
| 980 | } | 981 | } |
| 982 | EXPORT_SYMBOL(datagram_poll_queue); | ||
| 983 | |||
| 984 | /** | ||
| 985 | * datagram_poll - generic datagram poll | ||
| 986 | * @file: file struct | ||
| 987 | * @sock: socket | ||
| 988 | * @wait: poll table | ||
| 989 | * | ||
| 990 | * Datagram poll: Again totally generic. This also handles | ||
| 991 | * sequenced packet sockets providing the socket receive queue | ||
| 992 | * is only ever holding data ready to receive. | ||
| 993 | * | ||
| 994 | * Note: when you *don't* use this routine for this protocol, | ||
| 995 | * and you use a different write policy from sock_writeable() | ||
| 996 | * then please supply your own write_space callback. | ||
| 997 | * | ||
| 998 | * Return: poll bitmask indicating the socket's current state | ||
| 999 | */ | ||
| 1000 | __poll_t datagram_poll(struct file *file, struct socket *sock, poll_table *wait) | ||
| 1001 | { | ||
| 1002 | return datagram_poll_queue(file, sock, wait, | ||
| 1003 | &sock->sk->sk_receive_queue); | ||
| 1004 | } | ||
| 981 | EXPORT_SYMBOL(datagram_poll); | 1005 | EXPORT_SYMBOL(datagram_poll); |