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: Cong Wang <cong.wang@bytedance.com> Signed-off-by: Alexei Starovoitov <ast@kernel.org> Acked-by: John Fastabend <john.fastabend@gmail.com> Link: https://lore.kernel.org/bpf/20210331023237.41094-12-xiyou.wangcong@gmail.com
This commit is contained in:
parent
8a59f9d1e3
commit
d7f571188e
@ -329,6 +329,8 @@ struct sock *__udp6_lib_lookup(struct net *net,
|
|||||||
struct sk_buff *skb);
|
struct sk_buff *skb);
|
||||||
struct sock *udp6_lib_lookup_skb(const struct sk_buff *skb,
|
struct sock *udp6_lib_lookup_skb(const struct sk_buff *skb,
|
||||||
__be16 sport, __be16 dport);
|
__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
|
/* UDP uses skb->dev_scratch to cache as much information as possible and avoid
|
||||||
* possibly multiple cache miss on dequeue()
|
* possibly multiple cache miss on dequeue()
|
||||||
|
@ -1070,6 +1070,7 @@ const struct proto_ops inet_dgram_ops = {
|
|||||||
.setsockopt = sock_common_setsockopt,
|
.setsockopt = sock_common_setsockopt,
|
||||||
.getsockopt = sock_common_getsockopt,
|
.getsockopt = sock_common_getsockopt,
|
||||||
.sendmsg = inet_sendmsg,
|
.sendmsg = inet_sendmsg,
|
||||||
|
.read_sock = udp_read_sock,
|
||||||
.recvmsg = inet_recvmsg,
|
.recvmsg = inet_recvmsg,
|
||||||
.mmap = sock_no_mmap,
|
.mmap = sock_no_mmap,
|
||||||
.sendpage = inet_sendpage,
|
.sendpage = inet_sendpage,
|
||||||
|
@ -1782,6 +1782,35 @@ busy_check:
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL(__skb_recv_udp);
|
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
|
* This should be easy, if there is something there we
|
||||||
* return it, otherwise we block.
|
* return it, otherwise we block.
|
||||||
|
@ -714,6 +714,7 @@ const struct proto_ops inet6_dgram_ops = {
|
|||||||
.getsockopt = sock_common_getsockopt, /* ok */
|
.getsockopt = sock_common_getsockopt, /* ok */
|
||||||
.sendmsg = inet6_sendmsg, /* retpoline's sake */
|
.sendmsg = inet6_sendmsg, /* retpoline's sake */
|
||||||
.recvmsg = inet6_recvmsg, /* retpoline's sake */
|
.recvmsg = inet6_recvmsg, /* retpoline's sake */
|
||||||
|
.read_sock = udp_read_sock,
|
||||||
.mmap = sock_no_mmap,
|
.mmap = sock_no_mmap,
|
||||||
.sendpage = sock_no_sendpage,
|
.sendpage = sock_no_sendpage,
|
||||||
.set_peek_off = sk_set_peek_off,
|
.set_peek_off = sk_set_peek_off,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user