Commit d7f57118 authored by Cong Wang's avatar Cong Wang Committed by Alexei Starovoitov
Browse files

udp: Implement ->read_sock() for sockmap



This is similar to tcp_read_sock(), except we do not need
to worry about connections, we just need to retrieve skb
from UDP receive queue.

Note, the return value of ->read_sock() is unused in
sk_psock_verdict_data_ready(), and UDP still does not
support splice() due to lack of ->splice_read(), so users
can not reach udp_read_sock() directly.

Signed-off-by: default avatarCong Wang <cong.wang@bytedance.com>
Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
Acked-by: default avatarJohn Fastabend <john.fastabend@gmail.com>
Link: https://lore.kernel.org/bpf/20210331023237.41094-12-xiyou.wangcong@gmail.com
parent 8a59f9d1
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -329,6 +329,8 @@ struct sock *__udp6_lib_lookup(struct net *net,
			       struct sk_buff *skb);
struct sock *udp6_lib_lookup_skb(const struct sk_buff *skb,
				 __be16 sport, __be16 dport);
int udp_read_sock(struct sock *sk, read_descriptor_t *desc,
		  sk_read_actor_t recv_actor);

/* UDP uses skb->dev_scratch to cache as much information as possible and avoid
 * possibly multiple cache miss on dequeue()
+1 −0
Original line number Diff line number Diff line
@@ -1070,6 +1070,7 @@ const struct proto_ops inet_dgram_ops = {
	.setsockopt	   = sock_common_setsockopt,
	.getsockopt	   = sock_common_getsockopt,
	.sendmsg	   = inet_sendmsg,
	.read_sock	   = udp_read_sock,
	.recvmsg	   = inet_recvmsg,
	.mmap		   = sock_no_mmap,
	.sendpage	   = inet_sendpage,
+29 −0
Original line number Diff line number Diff line
@@ -1782,6 +1782,35 @@ struct sk_buff *__skb_recv_udp(struct sock *sk, unsigned int flags,
}
EXPORT_SYMBOL(__skb_recv_udp);

int udp_read_sock(struct sock *sk, read_descriptor_t *desc,
		  sk_read_actor_t recv_actor)
{
	int copied = 0;

	while (1) {
		struct sk_buff *skb;
		int err, used;

		skb = skb_recv_udp(sk, 0, 1, &err);
		if (!skb)
			return err;
		used = recv_actor(desc, skb, 0, skb->len);
		if (used <= 0) {
			if (!copied)
				copied = used;
			break;
		} else if (used <= skb->len) {
			copied += used;
		}

		if (!desc->count)
			break;
	}

	return copied;
}
EXPORT_SYMBOL(udp_read_sock);

/*
 * 	This should be easy, if there is something there we
 * 	return it, otherwise we block.
+1 −0
Original line number Diff line number Diff line
@@ -714,6 +714,7 @@ const struct proto_ops inet6_dgram_ops = {
	.getsockopt	   = sock_common_getsockopt,	/* ok		*/
	.sendmsg	   = inet6_sendmsg,		/* retpoline's sake */
	.recvmsg	   = inet6_recvmsg,		/* retpoline's sake */
	.read_sock	   = udp_read_sock,
	.mmap		   = sock_no_mmap,
	.sendpage	   = sock_no_sendpage,
	.set_peek_off	   = sk_set_peek_off,