Re: [Patch bpf-next v3 05/10] af_unix: implement unix_dgram_bpf_recvmsg()
From: Jakub Sitnicki <jakub@cloudflare.com>
Date: 2021-05-07 13:29:49
Also in:
bpf
On Mon, Apr 26, 2021 at 04:49 AM CEST, Cong Wang wrote:
quoted hunk ↗ jump to hunk
From: Cong Wang <redacted> We have to implement unix_dgram_bpf_recvmsg() to replace the original ->recvmsg() to retrieve skmsg from ingress_msg. AF_UNIX is again special here because the lack of sk_prot->recvmsg(). I simply add a special case inside unix_dgram_recvmsg() to call sk->sk_prot->recvmsg() directly. 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/af_unix.h | 3 +++ net/unix/af_unix.c | 21 ++++++++++++++++--- net/unix/unix_bpf.c | 49 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 70 insertions(+), 3 deletions(-)diff --git a/include/net/af_unix.h b/include/net/af_unix.h index cca645846af1..e524c82794c9 100644 --- a/include/net/af_unix.h +++ b/include/net/af_unix.h@@ -82,6 +82,9 @@ static inline struct unix_sock *unix_sk(const struct sock *sk) long unix_inq_len(struct sock *sk); long unix_outq_len(struct sock *sk); +int __unix_dgram_recvmsg(struct sock *sk, struct msghdr *msg, size_t size, + int nonblock, int flags, int *addr_len); + #ifdef CONFIG_SYSCTL int unix_sysctl_register(struct net *net); void unix_sysctl_unregister(struct net *net);diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index c4afc5fbe137..08458fa9f48b 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c@@ -2088,11 +2088,11 @@ static void unix_copy_addr(struct msghdr *msg, struct sock *sk) } } -static int unix_dgram_recvmsg(struct socket *sock, struct msghdr *msg, - size_t size, int flags) +int __unix_dgram_recvmsg(struct sock *sk, struct msghdr *msg, size_t size, + int nonblock, int flags, int *addr_len) { struct scm_cookie scm; - struct sock *sk = sock->sk; + struct socket *sock = sk->sk_socket; struct unix_sock *u = unix_sk(sk); struct sk_buff *skb, *last; long timeo;@@ -2195,6 +2195,21 @@ static int unix_dgram_recvmsg(struct socket *sock, struct msghdr *msg, return err; } +static int unix_dgram_recvmsg(struct socket *sock, struct msghdr *msg, size_t size, + int flags) +{ + struct sock *sk = sock->sk; + int addr_len = 0; + +#ifdef CONFIG_BPF_SYSCALL + if (sk->sk_prot != &unix_proto) + return sk->sk_prot->recvmsg(sk, msg, size, flags & MSG_DONTWAIT, + flags & ~MSG_DONTWAIT, &addr_len); +#endif + return __unix_dgram_recvmsg(sk, msg, size, flags & MSG_DONTWAIT, + flags, &addr_len); +} +
Nit: We can just pass NULL instead of &addr_len here it seems. [...]