Thread (20 messages) 20 messages, 3 authors, 2021-03-27

Re: [Patch bpf-next v6 08/12] udp: implement ->read_sock() for sockmap

From: Cong Wang <hidden>
Date: 2021-03-24 20:06:00
Also in: bpf

On Mon, Mar 22, 2021 at 11:31 PM Yunsheng Lin [off-list ref] wrote:
On 2021/3/23 8:38, Cong Wang wrote:
quoted
From: Cong Wang <redacted>

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.

Cc: John Fastabend <john.fastabend@gmail.com>
Cc: Daniel Borkmann <daniel@iogearbox.net>
Cc: Jakub Sitnicki <jakub@cloudflare.com>
Cc: Lorenz Bauer <redacted>
Signed-off-by: Cong Wang <redacted>
---
 include/net/udp.h   |  2 ++
 net/ipv4/af_inet.c  |  1 +
 net/ipv4/udp.c      | 35 +++++++++++++++++++++++++++++++++++
 net/ipv6/af_inet6.c |  1 +
 4 files changed, 39 insertions(+)
diff --git a/include/net/udp.h b/include/net/udp.h
index df7cc1edc200..347b62a753c3 100644
--- a/include/net/udp.h
+++ b/include/net/udp.h
@@ -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()
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index 1355e6c0d567..f17870ee558b 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -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,
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index 38952aaee3a1..a0adee3b1af4 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -1782,6 +1782,41 @@ 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) {
+             int offset = 0, err;
+             struct sk_buff *skb;
+
+             skb = __skb_recv_udp(sk, 0, 1, &offset, &err);
+             if (!skb)
+                     break;
Does above error handling need the below additional handling?
It seems __skb_recv_udp() will return the error by parameter "err",
if "copied == 0", does it need to return the error?
Not for skmsg case, because the return value is just unused:

static void sk_psock_verdict_data_ready(struct sock *sk)
{
        struct socket *sock = sk->sk_socket;
        read_descriptor_t desc;

        if (unlikely(!sock || !sock->ops || !sock->ops->read_sock))
                return;

        desc.arg.data = sk;
        desc.error = 0;
        desc.count = 1;

        sock->ops->read_sock(sk, &desc, sk_psock_verdict_recv);
}

Thanks.
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help