This will be used by ESP over TCP to handle the queue of IKE messages.

Signed-off-by: Sabrina Dubroca <s...@queasysnail.net>
---
v2: document the new argument to __skb_try_recv_datagram

 include/linux/skbuff.h | 11 ++++++++---
 net/core/datagram.c    | 27 +++++++++++++++++----------
 net/ipv4/udp.c         |  3 ++-
 net/unix/af_unix.c     |  7 ++++---
 4 files changed, 31 insertions(+), 17 deletions(-)

diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 907209c0794e..c33cafb9d26f 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -3441,7 +3441,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,
@@ -3450,12 +3451,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);
diff --git a/net/core/datagram.c b/net/core/datagram.c
index 4cc8dc5db2b7..ef192359f707 100644
--- a/net/core/datagram.c
+++ b/net/core/datagram.c
@@ -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 (sk->sk_receive_queue.prev != skb)
+       if (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 (sk->sk_receive_queue.prev != *last);
+       } while (queue->prev != *last);
 
        error = -EAGAIN;
 
@@ -288,7 +291,9 @@ struct sk_buff *__skb_try_recv_datagram(struct sock *sk, 
unsigned int flags,
 }
 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);
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index fbcd9be3a470..2ce132c7a120 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -1676,7 +1676,8 @@ struct sk_buff *__skb_recv_udp(struct sock *sk, unsigned 
int flags,
 
                /* 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;
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index 67e87db5877f..93e004f97f48 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -2048,8 +2048,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;
 
@@ -2058,7 +2058,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);
-- 
2.23.0

Reply via email to