4
4
#include <linux/skmsg.h>
5
5
#include <net/sock.h>
6
6
#include <net/udp.h>
7
+ #include <net/inet_common.h>
8
+
9
+ #include "udp_impl.h"
10
+
11
+ static struct proto * udpv6_prot_saved __read_mostly ;
12
+
13
+ static int sk_udp_recvmsg (struct sock * sk , struct msghdr * msg , size_t len ,
14
+ int noblock , int flags , int * addr_len )
15
+ {
16
+ #if IS_ENABLED (CONFIG_IPV6 )
17
+ if (sk -> sk_family == AF_INET6 )
18
+ return udpv6_prot_saved -> recvmsg (sk , msg , len , noblock , flags ,
19
+ addr_len );
20
+ #endif
21
+ return udp_prot .recvmsg (sk , msg , len , noblock , flags , addr_len );
22
+ }
23
+
24
+ static int udp_bpf_recvmsg (struct sock * sk , struct msghdr * msg , size_t len ,
25
+ int nonblock , int flags , int * addr_len )
26
+ {
27
+ struct sk_psock * psock ;
28
+ int copied , ret ;
29
+
30
+ if (unlikely (flags & MSG_ERRQUEUE ))
31
+ return inet_recv_error (sk , msg , len , addr_len );
32
+
33
+ psock = sk_psock_get (sk );
34
+ if (unlikely (!psock ))
35
+ return sk_udp_recvmsg (sk , msg , len , nonblock , flags , addr_len );
36
+
37
+ lock_sock (sk );
38
+ if (sk_psock_queue_empty (psock )) {
39
+ ret = sk_udp_recvmsg (sk , msg , len , nonblock , flags , addr_len );
40
+ goto out ;
41
+ }
42
+
43
+ msg_bytes_ready :
44
+ copied = sk_msg_recvmsg (sk , psock , msg , len , flags );
45
+ if (!copied ) {
46
+ int data , err = 0 ;
47
+ long timeo ;
48
+
49
+ timeo = sock_rcvtimeo (sk , nonblock );
50
+ data = sk_msg_wait_data (sk , psock , flags , timeo , & err );
51
+ if (data ) {
52
+ if (!sk_psock_queue_empty (psock ))
53
+ goto msg_bytes_ready ;
54
+ ret = sk_udp_recvmsg (sk , msg , len , nonblock , flags , addr_len );
55
+ goto out ;
56
+ }
57
+ if (err ) {
58
+ ret = err ;
59
+ goto out ;
60
+ }
61
+ copied = - EAGAIN ;
62
+ }
63
+ ret = copied ;
64
+ out :
65
+ release_sock (sk );
66
+ sk_psock_put (sk , psock );
67
+ return ret ;
68
+ }
7
69
8
70
enum {
9
71
UDP_BPF_IPV4 ,
10
72
UDP_BPF_IPV6 ,
11
73
UDP_BPF_NUM_PROTS ,
12
74
};
13
75
14
- static struct proto * udpv6_prot_saved __read_mostly ;
15
76
static DEFINE_SPINLOCK (udpv6_prot_lock );
16
77
static struct proto udp_bpf_prots [UDP_BPF_NUM_PROTS ];
17
78
@@ -20,6 +81,7 @@ static void udp_bpf_rebuild_protos(struct proto *prot, const struct proto *base)
20
81
* prot = * base ;
21
82
prot -> unhash = sock_map_unhash ;
22
83
prot -> close = sock_map_close ;
84
+ prot -> recvmsg = udp_bpf_recvmsg ;
23
85
}
24
86
25
87
static void udp_bpf_check_v6_needs_rebuild (struct proto * ops )
0 commit comments