On Mon, 2023-09-11 at 03:34 -0700, Breno Leitao wrote: > Split __sys_getsockopt() into two functions by removing the core > logic into a sub-function (do_sock_getsockopt()). This will avoid > code duplication when executing the same operation in other callers, for > instance. > > do_sock_getsockopt() will be called by io_uring getsockopt() command > operation in the following patch. > > Suggested-by: Martin KaFai Lau <martin.lau@xxxxxxxxx> > Signed-off-by: Breno Leitao <leitao@xxxxxxxxxx> > --- > include/net/sock.h | 3 +++ > net/socket.c | 51 ++++++++++++++++++++++++++++------------------ > 2 files changed, 34 insertions(+), 20 deletions(-) > > diff --git a/include/net/sock.h b/include/net/sock.h > index aa8fb54ad0af..fbd568a43d28 100644 > --- a/include/net/sock.h > +++ b/include/net/sock.h > @@ -1863,6 +1863,9 @@ int sock_setsockopt(struct socket *sock, int level, int op, > sockptr_t optval, unsigned int optlen); > int do_sock_setsockopt(struct socket *sock, bool compat, int level, > int optname, char __user *user_optval, int optlen); > +int do_sock_getsockopt(struct socket *sock, bool compat, int level, > + int optname, char __user *user_optval, > + int __user *user_optlen); > > int sk_getsockopt(struct sock *sk, int level, int optname, > sockptr_t optval, sockptr_t optlen); > diff --git a/net/socket.c b/net/socket.c > index 360332e098d4..3ec779a56f79 100644 > --- a/net/socket.c > +++ b/net/socket.c > @@ -2333,28 +2333,17 @@ SYSCALL_DEFINE5(setsockopt, int, fd, int, level, int, optname, > INDIRECT_CALLABLE_DECLARE(bool tcp_bpf_bypass_getsockopt(int level, > int optname)); > > -/* > - * Get a socket option. Because we don't know the option lengths we have > - * to pass a user mode parameter for the protocols to sort out. > - */ > -int __sys_getsockopt(int fd, int level, int optname, char __user *optval, > - int __user *optlen) > +int do_sock_getsockopt(struct socket *sock, bool compat, int level, > + int optname, char __user *optval, > + int __user *optlen) > { > int max_optlen __maybe_unused; > const struct proto_ops *ops; > - int err, fput_needed; > - struct socket *sock; > - > - sock = sockfd_lookup_light(fd, &err, &fput_needed); > - if (!sock) > - return err; > + int err; > > err = security_socket_getsockopt(sock, level, optname); > if (err) > - goto out_put; > - > - if (!in_compat_syscall()) > - max_optlen = BPF_CGROUP_GETSOCKOPT_MAX_OPTLEN(optlen); > + return err; > > ops = READ_ONCE(sock->ops); > if (level == SOL_SOCKET) > @@ -2362,14 +2351,36 @@ int __sys_getsockopt(int fd, int level, int optname, char __user *optval, > else if (unlikely(!ops->getsockopt)) > err = -EOPNOTSUPP; > else > - err = ops->getsockopt(sock, level, optname, optval, > - optlen); > + err = ops->getsockopt(sock, level, optname, optval, optlen); > > - if (!in_compat_syscall()) > + if (!compat) { > + max_optlen = BPF_CGROUP_GETSOCKOPT_MAX_OPTLEN(optlen); > err = BPF_CGROUP_RUN_PROG_GETSOCKOPT(sock->sk, level, optname, > optval, optlen, max_optlen, > err); > -out_put: > + } > + > + return err; > +} > +EXPORT_SYMBOL(do_sock_getsockopt); > + > +/* Get a socket option. Because we don't know the option lengths we have > + * to pass a user mode parameter for the protocols to sort out. > + */ > +int __sys_getsockopt(int fd, int level, int optname, char __user *optval, > + int __user *optlen) > +{ > + int err, fput_needed; > + bool compat = in_compat_syscall(); > + struct socket *sock; Please respect the reverse x-mas tree order, thanks! Paolo