net: add queue argument to __skb_wait_for_more_packets and __skb_{,try_}recv_datagram
authorSabrina Dubroca <sd@queasysnail.net>
Mon, 25 Nov 2019 13:48:57 +0000 (14:48 +0100)
committerSteffen Klassert <steffen.klassert@secunet.com>
Mon, 9 Dec 2019 08:59:07 +0000 (09:59 +0100)
This will be used by ESP over TCP to handle the queue of IKE messages.

Signed-off-by: Sabrina Dubroca <sd@queasysnail.net>
Acked-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
include/linux/skbuff.h
net/core/datagram.c
net/ipv4/udp.c
net/unix/af_unix.c

index e9133bcf0544d12b2e3cfbaa6b2c5dab0d501ba8..49a10f9cc538a9dd39481fbcc701a91bddc17b17 100644 (file)
@@ -3459,7 +3459,8 @@ static inline void skb_frag_list_init(struct sk_buff *skb)
        for (iter = skb_shinfo(skb)->frag_list; iter; iter = iter->next)
 
 
-int __skb_wait_for_more_packets(struct sock *sk, int *err, long *timeo_p,
+int __skb_wait_for_more_packets(struct sock *sk, struct sk_buff_head *queue,
+                               int *err, long *timeo_p,
                                const struct sk_buff *skb);
 struct sk_buff *__skb_try_recv_from_queue(struct sock *sk,
                                          struct sk_buff_head *queue,
@@ -3468,12 +3469,16 @@ struct sk_buff *__skb_try_recv_from_queue(struct sock *sk,
                                                           struct sk_buff *skb),
                                          int *off, int *err,
                                          struct sk_buff **last);
-struct sk_buff *__skb_try_recv_datagram(struct sock *sk, unsigned flags,
+struct sk_buff *__skb_try_recv_datagram(struct sock *sk,
+                                       struct sk_buff_head *queue,
+                                       unsigned int flags,
                                        void (*destructor)(struct sock *sk,
                                                           struct sk_buff *skb),
                                        int *off, int *err,
                                        struct sk_buff **last);
-struct sk_buff *__skb_recv_datagram(struct sock *sk, unsigned flags,
+struct sk_buff *__skb_recv_datagram(struct sock *sk,
+                                   struct sk_buff_head *sk_queue,
+                                   unsigned int flags,
                                    void (*destructor)(struct sock *sk,
                                                       struct sk_buff *skb),
                                    int *off, int *err);
index da3c24ed129cd64db8bdb1916afa552a47c1a5a3..a78e7f864c1e1d51cddd21ecfd7fc736b410d778 100644 (file)
@@ -84,7 +84,8 @@ static int receiver_wake_function(wait_queue_entry_t *wait, unsigned int mode, i
 /*
  * Wait for the last received packet to be different from skb
  */
-int __skb_wait_for_more_packets(struct sock *sk, int *err, long *timeo_p,
+int __skb_wait_for_more_packets(struct sock *sk, struct sk_buff_head *queue,
+                               int *err, long *timeo_p,
                                const struct sk_buff *skb)
 {
        int error;
@@ -97,7 +98,7 @@ int __skb_wait_for_more_packets(struct sock *sk, int *err, long *timeo_p,
        if (error)
                goto out_err;
 
-       if (READ_ONCE(sk->sk_receive_queue.prev) != skb)
+       if (READ_ONCE(queue->prev) != skb)
                goto out;
 
        /* Socket shut down? */
@@ -209,6 +210,7 @@ struct sk_buff *__skb_try_recv_from_queue(struct sock *sk,
 /**
  *     __skb_try_recv_datagram - Receive a datagram skbuff
  *     @sk: socket
+ *     @queue: socket queue from which to receive
  *     @flags: MSG\_ flags
  *     @destructor: invoked under the receive lock on successful dequeue
  *     @off: an offset in bytes to peek skb from. Returns an offset
@@ -241,13 +243,14 @@ struct sk_buff *__skb_try_recv_from_queue(struct sock *sk,
  *     quite explicitly by POSIX 1003.1g, don't change them without having
  *     the standard around please.
  */
-struct sk_buff *__skb_try_recv_datagram(struct sock *sk, unsigned int flags,
+struct sk_buff *__skb_try_recv_datagram(struct sock *sk,
+                                       struct sk_buff_head *queue,
+                                       unsigned int flags,
                                        void (*destructor)(struct sock *sk,
                                                           struct sk_buff *skb),
                                        int *off, int *err,
                                        struct sk_buff **last)
 {
-       struct sk_buff_head *queue = &sk->sk_receive_queue;
        struct sk_buff *skb;
        unsigned long cpu_flags;
        /*
@@ -278,7 +281,7 @@ struct sk_buff *__skb_try_recv_datagram(struct sock *sk, unsigned int flags,
                        break;
 
                sk_busy_loop(sk, flags & MSG_DONTWAIT);
-       } while (READ_ONCE(sk->sk_receive_queue.prev) != *last);
+       } while (READ_ONCE(queue->prev) != *last);
 
        error = -EAGAIN;
 
@@ -288,7 +291,9 @@ no_packet:
 }
 EXPORT_SYMBOL(__skb_try_recv_datagram);
 
-struct sk_buff *__skb_recv_datagram(struct sock *sk, unsigned int flags,
+struct sk_buff *__skb_recv_datagram(struct sock *sk,
+                                   struct sk_buff_head *sk_queue,
+                                   unsigned int flags,
                                    void (*destructor)(struct sock *sk,
                                                       struct sk_buff *skb),
                                    int *off, int *err)
@@ -299,15 +304,16 @@ struct sk_buff *__skb_recv_datagram(struct sock *sk, unsigned int flags,
        timeo = sock_rcvtimeo(sk, flags & MSG_DONTWAIT);
 
        do {
-               skb = __skb_try_recv_datagram(sk, flags, destructor, off, err,
-                                             &last);
+               skb = __skb_try_recv_datagram(sk, sk_queue, flags, destructor,
+                                             off, err, &last);
                if (skb)
                        return skb;
 
                if (*err != -EAGAIN)
                        break;
        } while (timeo &&
-               !__skb_wait_for_more_packets(sk, err, &timeo, last));
+                !__skb_wait_for_more_packets(sk, sk_queue, err,
+                                             &timeo, last));
 
        return NULL;
 }
@@ -318,7 +324,8 @@ struct sk_buff *skb_recv_datagram(struct sock *sk, unsigned int flags,
 {
        int off = 0;
 
-       return __skb_recv_datagram(sk, flags | (noblock ? MSG_DONTWAIT : 0),
+       return __skb_recv_datagram(sk, &sk->sk_receive_queue,
+                                  flags | (noblock ? MSG_DONTWAIT : 0),
                                   NULL, &off, err);
 }
 EXPORT_SYMBOL(skb_recv_datagram);
index 4da5758cc718739b63c7dda65cf889869b3b6141..e5738d1217a1a578a8da0bc1aef4eb78211056bd 100644 (file)
@@ -1708,7 +1708,8 @@ busy_check:
 
                /* sk_queue is empty, reader_queue may contain peeked packets */
        } while (timeo &&
-                !__skb_wait_for_more_packets(sk, &error, &timeo,
+                !__skb_wait_for_more_packets(sk, &sk->sk_receive_queue,
+                                             &error, &timeo,
                                              (struct sk_buff *)sk_queue));
 
        *err = error;
index 7cfdce10de36b70104229e122d76aea272d80a05..a7f707fc4cac575c95c53384685bd89402bfe4ed 100644 (file)
@@ -2058,8 +2058,8 @@ static int unix_dgram_recvmsg(struct socket *sock, struct msghdr *msg,
                mutex_lock(&u->iolock);
 
                skip = sk_peek_offset(sk, flags);
-               skb = __skb_try_recv_datagram(sk, flags, NULL, &skip, &err,
-                                             &last);
+               skb = __skb_try_recv_datagram(sk, &sk->sk_receive_queue, flags,
+                                             NULL, &skip, &err, &last);
                if (skb)
                        break;
 
@@ -2068,7 +2068,8 @@ static int unix_dgram_recvmsg(struct socket *sock, struct msghdr *msg,
                if (err != -EAGAIN)
                        break;
        } while (timeo &&
-                !__skb_wait_for_more_packets(sk, &err, &timeo, last));
+                !__skb_wait_for_more_packets(sk, &sk->sk_receive_queue,
+                                             &err, &timeo, last));
 
        if (!skb) { /* implies iolock unlocked */
                unix_state_lock(sk);