Commit b50b0580 authored by Sabrina Dubroca's avatar Sabrina Dubroca Committed by Steffen Klassert
Browse files

net: add queue argument to __skb_wait_for_more_packets and __skb_{,try_}recv_datagram



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

Signed-off-by: default avatarSabrina Dubroca <sd@queasysnail.net>
Acked-by: default avatarDavid S. Miller <davem@davemloft.net>
Signed-off-by: default avatarSteffen Klassert <steffen.klassert@secunet.com>
parent e7096c13
Loading
Loading
Loading
Loading
+8 −3
Original line number Original line Diff line number Diff line
@@ -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)
	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);
				const struct sk_buff *skb);
struct sk_buff *__skb_try_recv_from_queue(struct sock *sk,
struct sk_buff *__skb_try_recv_from_queue(struct sock *sk,
					  struct sk_buff_head *queue,
					  struct sk_buff_head *queue,
@@ -3468,12 +3469,16 @@ struct sk_buff *__skb_try_recv_from_queue(struct sock *sk,
							   struct sk_buff *skb),
							   struct sk_buff *skb),
					  int *off, int *err,
					  int *off, int *err,
					  struct sk_buff **last);
					  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,
					void (*destructor)(struct sock *sk,
							   struct sk_buff *skb),
							   struct sk_buff *skb),
					int *off, int *err,
					int *off, int *err,
					struct sk_buff **last);
					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,
				    void (*destructor)(struct sock *sk,
						       struct sk_buff *skb),
						       struct sk_buff *skb),
				    int *off, int *err);
				    int *off, int *err);
+17 −10
Original line number Original line Diff line number Diff line
@@ -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
 * 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)
				const struct sk_buff *skb)
{
{
	int error;
	int error;
@@ -97,7 +98,7 @@ int __skb_wait_for_more_packets(struct sock *sk, int *err, long *timeo_p,
	if (error)
	if (error)
		goto out_err;
		goto out_err;


	if (READ_ONCE(sk->sk_receive_queue.prev) != skb)
	if (READ_ONCE(queue->prev) != skb)
		goto out;
		goto out;


	/* Socket shut down? */
	/* 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
 *	__skb_try_recv_datagram - Receive a datagram skbuff
 *	@sk: socket
 *	@sk: socket
 *	@queue: socket queue from which to receive
 *	@flags: MSG\_ flags
 *	@flags: MSG\_ flags
 *	@destructor: invoked under the receive lock on successful dequeue
 *	@destructor: invoked under the receive lock on successful dequeue
 *	@off: an offset in bytes to peek skb from. Returns an offset
 *	@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
 *	quite explicitly by POSIX 1003.1g, don't change them without having
 *	the standard around please.
 *	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,
					void (*destructor)(struct sock *sk,
							   struct sk_buff *skb),
							   struct sk_buff *skb),
					int *off, int *err,
					int *off, int *err,
					struct sk_buff **last)
					struct sk_buff **last)
{
{
	struct sk_buff_head *queue = &sk->sk_receive_queue;
	struct sk_buff *skb;
	struct sk_buff *skb;
	unsigned long cpu_flags;
	unsigned long cpu_flags;
	/*
	/*
@@ -278,7 +281,7 @@ struct sk_buff *__skb_try_recv_datagram(struct sock *sk, unsigned int flags,
			break;
			break;


		sk_busy_loop(sk, flags & MSG_DONTWAIT);
		sk_busy_loop(sk, flags & MSG_DONTWAIT);
	} while (READ_ONCE(sk->sk_receive_queue.prev) != *last);
	} while (READ_ONCE(queue->prev) != *last);


	error = -EAGAIN;
	error = -EAGAIN;


@@ -288,7 +291,9 @@ no_packet:
}
}
EXPORT_SYMBOL(__skb_try_recv_datagram);
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,
				    void (*destructor)(struct sock *sk,
						       struct sk_buff *skb),
						       struct sk_buff *skb),
				    int *off, int *err)
				    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);
	timeo = sock_rcvtimeo(sk, flags & MSG_DONTWAIT);


	do {
	do {
		skb = __skb_try_recv_datagram(sk, flags, destructor, off, err,
		skb = __skb_try_recv_datagram(sk, sk_queue, flags, destructor,
					      &last);
					      off, err, &last);
		if (skb)
		if (skb)
			return skb;
			return skb;


		if (*err != -EAGAIN)
		if (*err != -EAGAIN)
			break;
			break;
	} while (timeo &&
	} while (timeo &&
		!__skb_wait_for_more_packets(sk, err, &timeo, last));
		 !__skb_wait_for_more_packets(sk, sk_queue, err,
					      &timeo, last));


	return NULL;
	return NULL;
}
}
@@ -318,7 +324,8 @@ struct sk_buff *skb_recv_datagram(struct sock *sk, unsigned int flags,
{
{
	int off = 0;
	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);
				   NULL, &off, err);
}
}
EXPORT_SYMBOL(skb_recv_datagram);
EXPORT_SYMBOL(skb_recv_datagram);
+2 −1
Original line number Original line Diff line number Diff line
@@ -1708,7 +1708,8 @@ busy_check:


		/* sk_queue is empty, reader_queue may contain peeked packets */
		/* sk_queue is empty, reader_queue may contain peeked packets */
	} while (timeo &&
	} 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));
					      (struct sk_buff *)sk_queue));


	*err = error;
	*err = error;
+4 −3
Original line number Original line Diff line number Diff line
@@ -2058,8 +2058,8 @@ static int unix_dgram_recvmsg(struct socket *sock, struct msghdr *msg,
		mutex_lock(&u->iolock);
		mutex_lock(&u->iolock);


		skip = sk_peek_offset(sk, flags);
		skip = sk_peek_offset(sk, flags);
		skb = __skb_try_recv_datagram(sk, flags, NULL, &skip, &err,
		skb = __skb_try_recv_datagram(sk, &sk->sk_receive_queue, flags,
					      &last);
					      NULL, &skip, &err, &last);
		if (skb)
		if (skb)
			break;
			break;


@@ -2068,7 +2068,8 @@ static int unix_dgram_recvmsg(struct socket *sock, struct msghdr *msg,
		if (err != -EAGAIN)
		if (err != -EAGAIN)
			break;
			break;
	} while (timeo &&
	} 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 */
	if (!skb) { /* implies iolock unlocked */
		unix_state_lock(sk);
		unix_state_lock(sk);