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 | 4204 | struct sk_buff_head *sk_queue, |
| 4205 | 4205 | unsigned int flags, int *off, int *err); |
| 4206 | 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 | 4210 | __poll_t datagram_poll(struct file *file, struct socket *sock, |
| 4208 | 4211 | struct poll_table_struct *wait); |
| 4209 | 4212 | int skb_copy_datagram_iter(const struct sk_buff *from, int offset, |
| @@ -920,21 +920,22 @@ fault: · 919 unmodified lines | ||
| 920 | 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 | 925 | * @file: file struct |
| 925 | 926 | * @sock: socket |
| 926 | 927 | * @wait: poll table |
| 928 | + * @rcv_queue: receive queue to poll | |
| 927 | 929 | * |
| 928 | − * Datagram poll: Again totally generic. This also handles | |
| 929 | − * sequenced packet sockets providing the socket receive queue | |
| 930 | − * is only ever holding data ready to receive. | |
| 930 | + * Performs polling on the given receive queue, handling shutdown, error, | |
| 931 | + * and connection state. This is useful for protocols that deliver | |
| 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, | |
| 933 | − * and you use a different write policy from sock_writeable() | |
| 934 | − * then please supply your own write_space callback. | |
| 935 | + * Return: poll bitmask indicating the socket's current state | |
| 935 | 936 | */ |
| 936 | −__poll_t datagram_poll(struct file *file, struct socket *sock, | |
| 937 | − poll_table *wait) | |
| 937 | +__poll_t datagram_poll_queue(struct file *file, struct socket *sock, | |
| 938 | + poll_table *wait, struct sk_buff_head *rcv_queue) | |
| 938 | 939 | { |
| 939 | 940 | struct sock *sk = sock->sk; |
| 940 | 941 | __poll_t mask; |
| @@ -956,7 +957,7 @@ __poll_t datagram_poll(struct file *file, struct socket *sock, · 15 unmodified lines | ||
| 956 | 957 | mask |= EPOLLHUP; |
| 957 | 958 | |
| 958 | 959 | /* readable? */ |
| 959 | − if (!skb_queue_empty_lockless(&sk->sk_receive_queue)) | |
| 960 | + if (!skb_queue_empty_lockless(rcv_queue)) | |
| 960 | 961 | mask |= EPOLLIN | EPOLLRDNORM; |
| 961 | 962 | |
| 962 | 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 | 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 | 1005 | EXPORT_SYMBOL(datagram_poll); |