Skip to content

Commit 1f5be6b

Browse files
Cong WangAlexei Starovoitov
Cong Wang
authored and
Alexei Starovoitov
committed
udp: Implement udp_bpf_recvmsg() for sockmap
We have to implement udp_bpf_recvmsg() to replace the ->recvmsg() to retrieve skmsg from ingress_msg. Signed-off-by: Cong Wang <[email protected]> Signed-off-by: Alexei Starovoitov <[email protected]> Acked-by: John Fastabend <[email protected]> Link: https://lore.kernel.org/bpf/[email protected]
1 parent 2bc793e commit 1f5be6b

File tree

1 file changed

+63
-1
lines changed

1 file changed

+63
-1
lines changed

net/ipv4/udp_bpf.c

+63-1
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,75 @@
44
#include <linux/skmsg.h>
55
#include <net/sock.h>
66
#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+
}
769

870
enum {
971
UDP_BPF_IPV4,
1072
UDP_BPF_IPV6,
1173
UDP_BPF_NUM_PROTS,
1274
};
1375

14-
static struct proto *udpv6_prot_saved __read_mostly;
1576
static DEFINE_SPINLOCK(udpv6_prot_lock);
1677
static struct proto udp_bpf_prots[UDP_BPF_NUM_PROTS];
1778

@@ -20,6 +81,7 @@ static void udp_bpf_rebuild_protos(struct proto *prot, const struct proto *base)
2081
*prot = *base;
2182
prot->unhash = sock_map_unhash;
2283
prot->close = sock_map_close;
84+
prot->recvmsg = udp_bpf_recvmsg;
2385
}
2486

2587
static void udp_bpf_check_v6_needs_rebuild(struct proto *ops)

0 commit comments

Comments
 (0)