* [PATCH RESEND v2 0/3] Introduce getsockname io_uring_cmd
@ 2025-11-21 16:09 Gabriel Krisman Bertazi
2025-11-21 16:09 ` [PATCH v2 1/3] socket: Unify getsockname and getpeername implementation Gabriel Krisman Bertazi
` (2 more replies)
0 siblings, 3 replies; 8+ messages in thread
From: Gabriel Krisman Bertazi @ 2025-11-21 16:09 UTC (permalink / raw)
To: Jens Axboe
Cc: Gabriel Krisman Bertazi, netdev, io-uring, Jakub Kicinski,
David S. Miller, Eric Dumazet, Kuniyuki Iwashima, Paolo Abeni,
Willem de Bruijn, Simon Horman
[Resending v2 because silly git-format-patch doesn't To from
the branch description, only Cc, so it was missing Jen]s.
Since V1:
- minor style fixes
- Resend with (more) maintainers cc'ed
- rebased to axboe/for-next.
--
This feature has been requested a few times in the liburing repository
and Discord channels, such as in [1,2]. If anything, it also helps
solve a long standing issue in the bind-listen test that results in
occasional test failures.
The patchset is divided in three parts: Patch 1 merges the getpeername
and getsockname implementation in the network layer, making further
patches easier; Patch 2 splits out a helper used by io_uring, like done
for other network commands; Finally, patch 3 plumbs the new command in
io_uring.
The syscall path was tested by booting a Linux distro, which does all
sorts of getsockname/getpeername syscalls. The io_uring side was tested
with a couple of new liburing subtests available at:
https://github.com/krisman/liburing.git -b socket
Based on top of Jens' for-next.
[1] https://github.com/axboe/liburing/issues/1356
[2] https://discord.com/channels/1241076672589991966/1241076672589991970/1429975797912830074
---
CC: netdev@vger.kernel.org
CC: io-uring@vger.kernel.org
CC: Jakub Kicinski <kuba@kernel.org>
CC: David S. Miller <davem@davemloft.net>
CC: Eric Dumazet <edumazet@google.com>
CC: Kuniyuki Iwashima <kuniyu@google.com>
CC: Paolo Abeni <pabeni@redhat.com>
CC: Willem de Bruijn <willemb@google.com>
CC: Simon Horman <horms@kernel.org>
Gabriel Krisman Bertazi (3):
socket: Unify getsockname and getpeername implementation
socket: Split out a getsockname helper for io_uring
io_uring: Introduce getsockname io_uring cmd
include/linux/socket.h | 6 +--
include/uapi/linux/io_uring.h | 1 +
io_uring/cmd_net.c | 23 ++++++++++++
net/compat.c | 4 +-
net/socket.c | 69 +++++++++++------------------------
5 files changed, 51 insertions(+), 52 deletions(-)
--
2.51.0
^ permalink raw reply [flat|nested] 8+ messages in thread* [PATCH v2 1/3] socket: Unify getsockname and getpeername implementation 2025-11-21 16:09 [PATCH RESEND v2 0/3] Introduce getsockname io_uring_cmd Gabriel Krisman Bertazi @ 2025-11-21 16:09 ` Gabriel Krisman Bertazi 2025-11-22 1:20 ` Jakub Kicinski 2025-11-22 2:14 ` Kuniyuki Iwashima 2025-11-21 16:09 ` [PATCH v2 2/3] socket: Split out a getsockname helper for io_uring Gabriel Krisman Bertazi 2025-11-21 16:09 ` [PATCH v2 3/3] io_uring: Introduce getsockname io_uring cmd Gabriel Krisman Bertazi 2 siblings, 2 replies; 8+ messages in thread From: Gabriel Krisman Bertazi @ 2025-11-21 16:09 UTC (permalink / raw) To: Jens Axboe Cc: Gabriel Krisman Bertazi, netdev, io-uring, Jakub Kicinski, David S. Miller, Eric Dumazet, Kuniyuki Iwashima, Paolo Abeni, Willem de Bruijn, Simon Horman They are already implemented by the same get_name hook in the protocol level. Bring the unification one level up to reduce code duplication in preparation to supporting these as io_uring operations. Signed-off-by: Gabriel Krisman Bertazi <krisman@suse.de> --- include/linux/socket.h | 4 +-- net/compat.c | 4 +-- net/socket.c | 55 ++++++++++-------------------------------- 3 files changed, 16 insertions(+), 47 deletions(-) diff --git a/include/linux/socket.h b/include/linux/socket.h index 3b262487ec06..937fe331ff1e 100644 --- a/include/linux/socket.h +++ b/include/linux/socket.h @@ -454,9 +454,7 @@ extern int __sys_connect(int fd, struct sockaddr __user *uservaddr, extern int __sys_listen(int fd, int backlog); extern int __sys_listen_socket(struct socket *sock, int backlog); extern int __sys_getsockname(int fd, struct sockaddr __user *usockaddr, - int __user *usockaddr_len); -extern int __sys_getpeername(int fd, struct sockaddr __user *usockaddr, - int __user *usockaddr_len); + int __user *usockaddr_len, int peer); extern int __sys_socketpair(int family, int type, int protocol, int __user *usockvec); extern int __sys_shutdown_sock(struct socket *sock, int how); diff --git a/net/compat.c b/net/compat.c index 485db8ee9b28..2c9bd0edac99 100644 --- a/net/compat.c +++ b/net/compat.c @@ -460,10 +460,10 @@ COMPAT_SYSCALL_DEFINE2(socketcall, int, call, u32 __user *, args) ret = __sys_accept4(a0, compat_ptr(a1), compat_ptr(a[2]), 0); break; case SYS_GETSOCKNAME: - ret = __sys_getsockname(a0, compat_ptr(a1), compat_ptr(a[2])); + ret = __sys_getsockname(a0, compat_ptr(a1), compat_ptr(a[2]), 0); break; case SYS_GETPEERNAME: - ret = __sys_getpeername(a0, compat_ptr(a1), compat_ptr(a[2])); + ret = __sys_getsockname(a0, compat_ptr(a1), compat_ptr(a[2]), 1); break; case SYS_SOCKETPAIR: ret = __sys_socketpair(a0, a1, a[2], compat_ptr(a[3])); diff --git a/net/socket.c b/net/socket.c index e8892b218708..ee438b9425da 100644 --- a/net/socket.c +++ b/net/socket.c @@ -2128,12 +2128,11 @@ SYSCALL_DEFINE3(connect, int, fd, struct sockaddr __user *, uservaddr, } /* - * Get the local address ('name') of a socket object. Move the obtained - * name to user space. + * Get the address (remote or local ('name')) of a socket object. Move the + * obtained name to user space. */ - int __sys_getsockname(int fd, struct sockaddr __user *usockaddr, - int __user *usockaddr_len) + int __user *usockaddr_len, int peer) { struct socket *sock; struct sockaddr_storage address; @@ -2146,11 +2145,14 @@ int __sys_getsockname(int fd, struct sockaddr __user *usockaddr, if (unlikely(!sock)) return -ENOTSOCK; - err = security_socket_getsockname(sock); + if (peer) + err = security_socket_getpeername(sock); + else + err = security_socket_getsockname(sock); if (err) return err; - err = READ_ONCE(sock->ops)->getname(sock, (struct sockaddr *)&address, 0); + err = READ_ONCE(sock->ops)->getname(sock, (struct sockaddr *)&address, peer); if (err < 0) return err; @@ -2161,44 +2163,13 @@ int __sys_getsockname(int fd, struct sockaddr __user *usockaddr, SYSCALL_DEFINE3(getsockname, int, fd, struct sockaddr __user *, usockaddr, int __user *, usockaddr_len) { - return __sys_getsockname(fd, usockaddr, usockaddr_len); -} - -/* - * Get the remote address ('name') of a socket object. Move the obtained - * name to user space. - */ - -int __sys_getpeername(int fd, struct sockaddr __user *usockaddr, - int __user *usockaddr_len) -{ - struct socket *sock; - struct sockaddr_storage address; - CLASS(fd, f)(fd); - int err; - - if (fd_empty(f)) - return -EBADF; - sock = sock_from_file(fd_file(f)); - if (unlikely(!sock)) - return -ENOTSOCK; - - err = security_socket_getpeername(sock); - if (err) - return err; - - err = READ_ONCE(sock->ops)->getname(sock, (struct sockaddr *)&address, 1); - if (err < 0) - return err; - - /* "err" is actually length in this case */ - return move_addr_to_user(&address, err, usockaddr, usockaddr_len); + return __sys_getsockname(fd, usockaddr, usockaddr_len, 0); } SYSCALL_DEFINE3(getpeername, int, fd, struct sockaddr __user *, usockaddr, int __user *, usockaddr_len) { - return __sys_getpeername(fd, usockaddr, usockaddr_len); + return __sys_getsockname(fd, usockaddr, usockaddr_len, 1); } /* @@ -3162,12 +3133,12 @@ SYSCALL_DEFINE2(socketcall, int, call, unsigned long __user *, args) case SYS_GETSOCKNAME: err = __sys_getsockname(a0, (struct sockaddr __user *)a1, - (int __user *)a[2]); + (int __user *)a[2], 0); break; case SYS_GETPEERNAME: err = - __sys_getpeername(a0, (struct sockaddr __user *)a1, - (int __user *)a[2]); + __sys_getsockname(a0, (struct sockaddr __user *)a1, + (int __user *)a[2], 1); break; case SYS_SOCKETPAIR: err = __sys_socketpair(a0, a1, a[2], (int __user *)a[3]); -- 2.51.0 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH v2 1/3] socket: Unify getsockname and getpeername implementation 2025-11-21 16:09 ` [PATCH v2 1/3] socket: Unify getsockname and getpeername implementation Gabriel Krisman Bertazi @ 2025-11-22 1:20 ` Jakub Kicinski 2025-11-22 2:14 ` Kuniyuki Iwashima 1 sibling, 0 replies; 8+ messages in thread From: Jakub Kicinski @ 2025-11-22 1:20 UTC (permalink / raw) To: Eric Dumazet, Kuniyuki Iwashima, Paolo Abeni, Willem de Bruijn Cc: Gabriel Krisman Bertazi, Jens Axboe, netdev, io-uring, David S. Miller, Simon Horman On Fri, 21 Nov 2025 11:09:46 -0500 Gabriel Krisman Bertazi wrote: > include/linux/socket.h | 4 +-- > net/compat.c | 4 +-- > net/socket.c | 55 ++++++++++-------------------------------- socket layer maintainers, please review ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v2 1/3] socket: Unify getsockname and getpeername implementation 2025-11-21 16:09 ` [PATCH v2 1/3] socket: Unify getsockname and getpeername implementation Gabriel Krisman Bertazi 2025-11-22 1:20 ` Jakub Kicinski @ 2025-11-22 2:14 ` Kuniyuki Iwashima 1 sibling, 0 replies; 8+ messages in thread From: Kuniyuki Iwashima @ 2025-11-22 2:14 UTC (permalink / raw) To: Gabriel Krisman Bertazi Cc: Jens Axboe, netdev, io-uring, Jakub Kicinski, David S. Miller, Eric Dumazet, Paolo Abeni, Willem de Bruijn, Simon Horman On Fri, Nov 21, 2025 at 8:10 AM Gabriel Krisman Bertazi <krisman@suse.de> wrote: > > They are already implemented by the same get_name hook in the protocol > level. Bring the unification one level up to reduce code duplication > in preparation to supporting these as io_uring operations. > > Signed-off-by: Gabriel Krisman Bertazi <krisman@suse.de> > --- > include/linux/socket.h | 4 +-- > net/compat.c | 4 +-- > net/socket.c | 55 ++++++++++-------------------------------- > 3 files changed, 16 insertions(+), 47 deletions(-) > > diff --git a/include/linux/socket.h b/include/linux/socket.h > index 3b262487ec06..937fe331ff1e 100644 > --- a/include/linux/socket.h > +++ b/include/linux/socket.h > @@ -454,9 +454,7 @@ extern int __sys_connect(int fd, struct sockaddr __user *uservaddr, > extern int __sys_listen(int fd, int backlog); > extern int __sys_listen_socket(struct socket *sock, int backlog); > extern int __sys_getsockname(int fd, struct sockaddr __user *usockaddr, > - int __user *usockaddr_len); > -extern int __sys_getpeername(int fd, struct sockaddr __user *usockaddr, > - int __user *usockaddr_len); > + int __user *usockaddr_len, int peer); > extern int __sys_socketpair(int family, int type, int protocol, > int __user *usockvec); > extern int __sys_shutdown_sock(struct socket *sock, int how); > diff --git a/net/compat.c b/net/compat.c > index 485db8ee9b28..2c9bd0edac99 100644 > --- a/net/compat.c > +++ b/net/compat.c > @@ -460,10 +460,10 @@ COMPAT_SYSCALL_DEFINE2(socketcall, int, call, u32 __user *, args) > ret = __sys_accept4(a0, compat_ptr(a1), compat_ptr(a[2]), 0); > break; > case SYS_GETSOCKNAME: > - ret = __sys_getsockname(a0, compat_ptr(a1), compat_ptr(a[2])); > + ret = __sys_getsockname(a0, compat_ptr(a1), compat_ptr(a[2]), 0); > break; > case SYS_GETPEERNAME: > - ret = __sys_getpeername(a0, compat_ptr(a1), compat_ptr(a[2])); > + ret = __sys_getsockname(a0, compat_ptr(a1), compat_ptr(a[2]), 1); > break; > case SYS_SOCKETPAIR: > ret = __sys_socketpair(a0, a1, a[2], compat_ptr(a[3])); > diff --git a/net/socket.c b/net/socket.c > index e8892b218708..ee438b9425da 100644 > --- a/net/socket.c > +++ b/net/socket.c > @@ -2128,12 +2128,11 @@ SYSCALL_DEFINE3(connect, int, fd, struct sockaddr __user *, uservaddr, > } > > /* > - * Get the local address ('name') of a socket object. Move the obtained > - * name to user space. > + * Get the address (remote or local ('name')) of a socket object. Move the nit: Get the remote or local address ('name') Otherwise, looks good. Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com> > + * obtained name to user space. > */ > - > int __sys_getsockname(int fd, struct sockaddr __user *usockaddr, > - int __user *usockaddr_len) > + int __user *usockaddr_len, int peer) > { > struct socket *sock; > struct sockaddr_storage address; > @@ -2146,11 +2145,14 @@ int __sys_getsockname(int fd, struct sockaddr __user *usockaddr, > if (unlikely(!sock)) > return -ENOTSOCK; > > - err = security_socket_getsockname(sock); > + if (peer) > + err = security_socket_getpeername(sock); > + else > + err = security_socket_getsockname(sock); > if (err) > return err; > > - err = READ_ONCE(sock->ops)->getname(sock, (struct sockaddr *)&address, 0); > + err = READ_ONCE(sock->ops)->getname(sock, (struct sockaddr *)&address, peer); > if (err < 0) > return err; > > @@ -2161,44 +2163,13 @@ int __sys_getsockname(int fd, struct sockaddr __user *usockaddr, > SYSCALL_DEFINE3(getsockname, int, fd, struct sockaddr __user *, usockaddr, > int __user *, usockaddr_len) > { > - return __sys_getsockname(fd, usockaddr, usockaddr_len); > -} > - > -/* > - * Get the remote address ('name') of a socket object. Move the obtained > - * name to user space. > - */ > - > -int __sys_getpeername(int fd, struct sockaddr __user *usockaddr, > - int __user *usockaddr_len) > -{ > - struct socket *sock; > - struct sockaddr_storage address; > - CLASS(fd, f)(fd); > - int err; > - > - if (fd_empty(f)) > - return -EBADF; > - sock = sock_from_file(fd_file(f)); > - if (unlikely(!sock)) > - return -ENOTSOCK; > - > - err = security_socket_getpeername(sock); > - if (err) > - return err; > - > - err = READ_ONCE(sock->ops)->getname(sock, (struct sockaddr *)&address, 1); > - if (err < 0) > - return err; > - > - /* "err" is actually length in this case */ > - return move_addr_to_user(&address, err, usockaddr, usockaddr_len); > + return __sys_getsockname(fd, usockaddr, usockaddr_len, 0); > } > > SYSCALL_DEFINE3(getpeername, int, fd, struct sockaddr __user *, usockaddr, > int __user *, usockaddr_len) > { > - return __sys_getpeername(fd, usockaddr, usockaddr_len); > + return __sys_getsockname(fd, usockaddr, usockaddr_len, 1); > } > > /* > @@ -3162,12 +3133,12 @@ SYSCALL_DEFINE2(socketcall, int, call, unsigned long __user *, args) > case SYS_GETSOCKNAME: > err = > __sys_getsockname(a0, (struct sockaddr __user *)a1, > - (int __user *)a[2]); > + (int __user *)a[2], 0); > break; > case SYS_GETPEERNAME: > err = > - __sys_getpeername(a0, (struct sockaddr __user *)a1, > - (int __user *)a[2]); > + __sys_getsockname(a0, (struct sockaddr __user *)a1, > + (int __user *)a[2], 1); > break; > case SYS_SOCKETPAIR: > err = __sys_socketpair(a0, a1, a[2], (int __user *)a[3]); > -- > 2.51.0 > ^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH v2 2/3] socket: Split out a getsockname helper for io_uring 2025-11-21 16:09 [PATCH RESEND v2 0/3] Introduce getsockname io_uring_cmd Gabriel Krisman Bertazi 2025-11-21 16:09 ` [PATCH v2 1/3] socket: Unify getsockname and getpeername implementation Gabriel Krisman Bertazi @ 2025-11-21 16:09 ` Gabriel Krisman Bertazi 2025-11-22 2:15 ` Kuniyuki Iwashima 2025-11-21 16:09 ` [PATCH v2 3/3] io_uring: Introduce getsockname io_uring cmd Gabriel Krisman Bertazi 2 siblings, 1 reply; 8+ messages in thread From: Gabriel Krisman Bertazi @ 2025-11-21 16:09 UTC (permalink / raw) To: Jens Axboe Cc: Gabriel Krisman Bertazi, netdev, io-uring, Jakub Kicinski, David S. Miller, Eric Dumazet, Kuniyuki Iwashima, Paolo Abeni, Willem de Bruijn, Simon Horman Similar to getsockopt, split out a helper to check security and issue the operation from the main handler that can be used by io_uring. Signed-off-by: Gabriel Krisman Bertazi <krisman@suse.de> --- include/linux/socket.h | 2 ++ net/socket.c | 34 +++++++++++++++++++--------------- 2 files changed, 21 insertions(+), 15 deletions(-) diff --git a/include/linux/socket.h b/include/linux/socket.h index 937fe331ff1e..5afb5ef2990c 100644 --- a/include/linux/socket.h +++ b/include/linux/socket.h @@ -453,6 +453,8 @@ extern int __sys_connect(int fd, struct sockaddr __user *uservaddr, int addrlen); extern int __sys_listen(int fd, int backlog); extern int __sys_listen_socket(struct socket *sock, int backlog); +extern int do_getsockname(struct socket *sock, struct sockaddr_storage *address, + int peer, struct sockaddr __user *usockaddr, int __user *usockaddr_len); extern int __sys_getsockname(int fd, struct sockaddr __user *usockaddr, int __user *usockaddr_len, int peer); extern int __sys_socketpair(int family, int type, int protocol, diff --git a/net/socket.c b/net/socket.c index ee438b9425da..9c110b529cdd 100644 --- a/net/socket.c +++ b/net/socket.c @@ -2127,6 +2127,24 @@ SYSCALL_DEFINE3(connect, int, fd, struct sockaddr __user *, uservaddr, return __sys_connect(fd, uservaddr, addrlen); } +int do_getsockname(struct socket *sock, struct sockaddr_storage *address, int peer, + struct sockaddr __user *usockaddr, int __user *usockaddr_len) +{ + int err; + + if (peer) + err = security_socket_getpeername(sock); + else + err = security_socket_getsockname(sock); + if (err) + return err; + err = READ_ONCE(sock->ops)->getname(sock, (struct sockaddr *)address, peer); + if (err < 0) + return err; + /* "err" is actually length in this case */ + return move_addr_to_user(address, err, usockaddr, usockaddr_len); +} + /* * Get the address (remote or local ('name')) of a socket object. Move the * obtained name to user space. @@ -2137,27 +2155,13 @@ int __sys_getsockname(int fd, struct sockaddr __user *usockaddr, struct socket *sock; struct sockaddr_storage address; CLASS(fd, f)(fd); - int err; if (fd_empty(f)) return -EBADF; sock = sock_from_file(fd_file(f)); if (unlikely(!sock)) return -ENOTSOCK; - - if (peer) - err = security_socket_getpeername(sock); - else - err = security_socket_getsockname(sock); - if (err) - return err; - - err = READ_ONCE(sock->ops)->getname(sock, (struct sockaddr *)&address, peer); - if (err < 0) - return err; - - /* "err" is actually length in this case */ - return move_addr_to_user(&address, err, usockaddr, usockaddr_len); + return do_getsockname(sock, &address, peer, usockaddr, usockaddr_len); } SYSCALL_DEFINE3(getsockname, int, fd, struct sockaddr __user *, usockaddr, -- 2.51.0 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH v2 2/3] socket: Split out a getsockname helper for io_uring 2025-11-21 16:09 ` [PATCH v2 2/3] socket: Split out a getsockname helper for io_uring Gabriel Krisman Bertazi @ 2025-11-22 2:15 ` Kuniyuki Iwashima 0 siblings, 0 replies; 8+ messages in thread From: Kuniyuki Iwashima @ 2025-11-22 2:15 UTC (permalink / raw) To: Gabriel Krisman Bertazi Cc: Jens Axboe, netdev, io-uring, Jakub Kicinski, David S. Miller, Eric Dumazet, Paolo Abeni, Willem de Bruijn, Simon Horman On Fri, Nov 21, 2025 at 8:10 AM Gabriel Krisman Bertazi <krisman@suse.de> wrote: > > Similar to getsockopt, split out a helper to check security and issue > the operation from the main handler that can be used by io_uring. > > Signed-off-by: Gabriel Krisman Bertazi <krisman@suse.de> > --- > include/linux/socket.h | 2 ++ > net/socket.c | 34 +++++++++++++++++++--------------- > 2 files changed, 21 insertions(+), 15 deletions(-) > > diff --git a/include/linux/socket.h b/include/linux/socket.h > index 937fe331ff1e..5afb5ef2990c 100644 > --- a/include/linux/socket.h > +++ b/include/linux/socket.h > @@ -453,6 +453,8 @@ extern int __sys_connect(int fd, struct sockaddr __user *uservaddr, > int addrlen); > extern int __sys_listen(int fd, int backlog); > extern int __sys_listen_socket(struct socket *sock, int backlog); > +extern int do_getsockname(struct socket *sock, struct sockaddr_storage *address, > + int peer, struct sockaddr __user *usockaddr, int __user *usockaddr_len); > extern int __sys_getsockname(int fd, struct sockaddr __user *usockaddr, > int __user *usockaddr_len, int peer); > extern int __sys_socketpair(int family, int type, int protocol, > diff --git a/net/socket.c b/net/socket.c > index ee438b9425da..9c110b529cdd 100644 > --- a/net/socket.c > +++ b/net/socket.c > @@ -2127,6 +2127,24 @@ SYSCALL_DEFINE3(connect, int, fd, struct sockaddr __user *, uservaddr, > return __sys_connect(fd, uservaddr, addrlen); > } > > +int do_getsockname(struct socket *sock, struct sockaddr_storage *address, int peer, > + struct sockaddr __user *usockaddr, int __user *usockaddr_len) > +{ > + int err; > + > + if (peer) > + err = security_socket_getpeername(sock); > + else > + err = security_socket_getsockname(sock); > + if (err) > + return err; > + err = READ_ONCE(sock->ops)->getname(sock, (struct sockaddr *)address, peer); > + if (err < 0) > + return err; > + /* "err" is actually length in this case */ > + return move_addr_to_user(address, err, usockaddr, usockaddr_len); > +} > + > /* > * Get the address (remote or local ('name')) of a socket object. Move the > * obtained name to user space. > @@ -2137,27 +2155,13 @@ int __sys_getsockname(int fd, struct sockaddr __user *usockaddr, > struct socket *sock; > struct sockaddr_storage address; Could you move this to do_getsockname() ? The patch 3 also does not need to define it. > CLASS(fd, f)(fd); > - int err; > > if (fd_empty(f)) > return -EBADF; > sock = sock_from_file(fd_file(f)); > if (unlikely(!sock)) > return -ENOTSOCK; > - > - if (peer) > - err = security_socket_getpeername(sock); > - else > - err = security_socket_getsockname(sock); > - if (err) > - return err; > - > - err = READ_ONCE(sock->ops)->getname(sock, (struct sockaddr *)&address, peer); > - if (err < 0) > - return err; > - > - /* "err" is actually length in this case */ > - return move_addr_to_user(&address, err, usockaddr, usockaddr_len); > + return do_getsockname(sock, &address, peer, usockaddr, usockaddr_len); > } > > SYSCALL_DEFINE3(getsockname, int, fd, struct sockaddr __user *, usockaddr, > -- > 2.51.0 > ^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH v2 3/3] io_uring: Introduce getsockname io_uring cmd 2025-11-21 16:09 [PATCH RESEND v2 0/3] Introduce getsockname io_uring_cmd Gabriel Krisman Bertazi 2025-11-21 16:09 ` [PATCH v2 1/3] socket: Unify getsockname and getpeername implementation Gabriel Krisman Bertazi 2025-11-21 16:09 ` [PATCH v2 2/3] socket: Split out a getsockname helper for io_uring Gabriel Krisman Bertazi @ 2025-11-21 16:09 ` Gabriel Krisman Bertazi 2 siblings, 0 replies; 8+ messages in thread From: Gabriel Krisman Bertazi @ 2025-11-21 16:09 UTC (permalink / raw) To: Jens Axboe Cc: Gabriel Krisman Bertazi, netdev, io-uring, Jakub Kicinski, David S. Miller, Eric Dumazet, Kuniyuki Iwashima, Paolo Abeni, Willem de Bruijn, Simon Horman Introduce a socket-specific io_uring_cmd to support getsockname/getpeername via io_uring. I made this an io_uring_cmd instead of a new operation to avoid polluting the command namespace with what is exclusively a socket operation. In addition, since we don't need to conform to existing interfaces, this merges the getsockname/getpeername in a single operation, since the implementation is pretty much the same. This has been frequently requested, for instance at [1] and more recently in the project Discord channel. The main use-case is to support fixed socket file descriptors. [1] https://github.com/axboe/liburing/issues/1356 Signed-off-by: Gabriel Krisman Bertazi <krisman@suse.de> --- include/uapi/linux/io_uring.h | 1 + io_uring/cmd_net.c | 23 +++++++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/include/uapi/linux/io_uring.h b/include/uapi/linux/io_uring.h index 3d921cbb84f8..6a97c5376019 100644 --- a/include/uapi/linux/io_uring.h +++ b/include/uapi/linux/io_uring.h @@ -1010,6 +1010,7 @@ enum io_uring_socket_op { SOCKET_URING_OP_GETSOCKOPT, SOCKET_URING_OP_SETSOCKOPT, SOCKET_URING_OP_TX_TIMESTAMP, + SOCKET_URING_OP_GETSOCKNAME, }; /* diff --git a/io_uring/cmd_net.c b/io_uring/cmd_net.c index 27a09aa4c9d0..90f58f883f62 100644 --- a/io_uring/cmd_net.c +++ b/io_uring/cmd_net.c @@ -132,6 +132,27 @@ static int io_uring_cmd_timestamp(struct socket *sock, return -EAGAIN; } +static int io_uring_cmd_getsockname(struct socket *sock, + struct io_uring_cmd *cmd, + unsigned int issue_flags) +{ + const struct io_uring_sqe *sqe = cmd->sqe; + struct sockaddr_storage address; + struct sockaddr __user *uaddr; + unsigned int peer; + int __user *ulen; + + if (sqe->ioprio || sqe->__pad1 || sqe->len || sqe->rw_flags) + return -EINVAL; + + uaddr = u64_to_user_ptr(READ_ONCE(sqe->addr)); + ulen = u64_to_user_ptr(sqe->addr3); + peer = READ_ONCE(sqe->optlen); + if (peer > 1) + return -EINVAL; + return do_getsockname(sock, &address, 0, uaddr, ulen); +} + int io_uring_cmd_sock(struct io_uring_cmd *cmd, unsigned int issue_flags) { struct socket *sock = cmd->file->private_data; @@ -159,6 +180,8 @@ int io_uring_cmd_sock(struct io_uring_cmd *cmd, unsigned int issue_flags) return io_uring_cmd_setsockopt(sock, cmd, issue_flags); case SOCKET_URING_OP_TX_TIMESTAMP: return io_uring_cmd_timestamp(sock, cmd, issue_flags); + case SOCKET_URING_OP_GETSOCKNAME: + return io_uring_cmd_getsockname(sock, cmd, issue_flags); default: return -EOPNOTSUPP; } -- 2.51.0 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH v2 0/3] Introduce getsockname io_uring_cmd @ 2025-11-20 21:58 Gabriel Krisman Bertazi 2025-11-20 21:58 ` [PATCH v2 3/3] io_uring: Introduce getsockname io_uring cmd Gabriel Krisman Bertazi 0 siblings, 1 reply; 8+ messages in thread From: Gabriel Krisman Bertazi @ 2025-11-20 21:58 UTC (permalink / raw) Cc: Gabriel Krisman Bertazi, netdev, io-uring, Jakub Kicinski, David S. Miller, Eric Dumazet, Kuniyuki Iwashima, Paolo Abeni, Willem de Bruijn, Simon Horman Since V1: - minor style fixes - Resend with (more) maintainers cc'ed - rebased to axboe/for-next. -- This feature has been requested a few times in the liburing repository and Discord channels, such as in [1,2]. If anything, it also helps solve a long standing issue in the bind-listen test that results in occasional test failures. The patchset is divided in three parts: Patch 1 merges the getpeername and getsockname implementation in the network layer, making further patches easier; Patch 2 splits out a helper used by io_uring, like done for other network commands; Finally, patch 3 plumbs the new command in io_uring. The syscall path was tested by booting a Linux distro, which does all sorts of getsockname/getpeername syscalls. The io_uring side was tested with a couple of new liburing subtests available at: https://github.com/krisman/liburing.git -b socket Based on top of Jens' for-next. [1] https://github.com/axboe/liburing/issues/1356 [2] https://discord.com/channels/1241076672589991966/1241076672589991970/1429975797912830074 --- To: Jens Axboe <axboe@kernel.dk> CC: netdev@vger.kernel.org CC: io-uring@vger.kernel.org CC: Jakub Kicinski <kuba@kernel.org> CC: David S. Miller <davem@davemloft.net> CC: Eric Dumazet <edumazet@google.com> CC: Kuniyuki Iwashima <kuniyu@google.com> CC: Paolo Abeni <pabeni@redhat.com> CC: Willem de Bruijn <willemb@google.com> CC: Simon Horman <horms@kernel.org> Base: axboe/for-next Gabriel Krisman Bertazi (3): socket: Unify getsockname and getpeername implementation socket: Split out a getsockname helper for io_uring io_uring: Introduce getsockname io_uring cmd include/linux/socket.h | 6 +-- include/uapi/linux/io_uring.h | 1 + io_uring/cmd_net.c | 23 ++++++++++++ net/compat.c | 4 +- net/socket.c | 69 +++++++++++------------------------ 5 files changed, 51 insertions(+), 52 deletions(-) -- 2.51.0 ^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH v2 3/3] io_uring: Introduce getsockname io_uring cmd 2025-11-20 21:58 [PATCH v2 0/3] Introduce getsockname io_uring_cmd Gabriel Krisman Bertazi @ 2025-11-20 21:58 ` Gabriel Krisman Bertazi 0 siblings, 0 replies; 8+ messages in thread From: Gabriel Krisman Bertazi @ 2025-11-20 21:58 UTC (permalink / raw) Cc: Gabriel Krisman Bertazi, netdev, io-uring, Jakub Kicinski, David S. Miller, Eric Dumazet, Kuniyuki Iwashima, Paolo Abeni, Willem de Bruijn, Simon Horman Introduce a socket-specific io_uring_cmd to support getsockname/getpeername via io_uring. I made this an io_uring_cmd instead of a new operation to avoid polluting the command namespace with what is exclusively a socket operation. In addition, since we don't need to conform to existing interfaces, this merges the getsockname/getpeername in a single operation, since the implementation is pretty much the same. This has been frequently requested, for instance at [1] and more recently in the project Discord channel. The main use-case is to support fixed socket file descriptors. [1] https://github.com/axboe/liburing/issues/1356 Signed-off-by: Gabriel Krisman Bertazi <krisman@suse.de> --- include/uapi/linux/io_uring.h | 1 + io_uring/cmd_net.c | 23 +++++++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/include/uapi/linux/io_uring.h b/include/uapi/linux/io_uring.h index 3d921cbb84f8..6a97c5376019 100644 --- a/include/uapi/linux/io_uring.h +++ b/include/uapi/linux/io_uring.h @@ -1010,6 +1010,7 @@ enum io_uring_socket_op { SOCKET_URING_OP_GETSOCKOPT, SOCKET_URING_OP_SETSOCKOPT, SOCKET_URING_OP_TX_TIMESTAMP, + SOCKET_URING_OP_GETSOCKNAME, }; /* diff --git a/io_uring/cmd_net.c b/io_uring/cmd_net.c index 27a09aa4c9d0..90f58f883f62 100644 --- a/io_uring/cmd_net.c +++ b/io_uring/cmd_net.c @@ -132,6 +132,27 @@ static int io_uring_cmd_timestamp(struct socket *sock, return -EAGAIN; } +static int io_uring_cmd_getsockname(struct socket *sock, + struct io_uring_cmd *cmd, + unsigned int issue_flags) +{ + const struct io_uring_sqe *sqe = cmd->sqe; + struct sockaddr_storage address; + struct sockaddr __user *uaddr; + unsigned int peer; + int __user *ulen; + + if (sqe->ioprio || sqe->__pad1 || sqe->len || sqe->rw_flags) + return -EINVAL; + + uaddr = u64_to_user_ptr(READ_ONCE(sqe->addr)); + ulen = u64_to_user_ptr(sqe->addr3); + peer = READ_ONCE(sqe->optlen); + if (peer > 1) + return -EINVAL; + return do_getsockname(sock, &address, 0, uaddr, ulen); +} + int io_uring_cmd_sock(struct io_uring_cmd *cmd, unsigned int issue_flags) { struct socket *sock = cmd->file->private_data; @@ -159,6 +180,8 @@ int io_uring_cmd_sock(struct io_uring_cmd *cmd, unsigned int issue_flags) return io_uring_cmd_setsockopt(sock, cmd, issue_flags); case SOCKET_URING_OP_TX_TIMESTAMP: return io_uring_cmd_timestamp(sock, cmd, issue_flags); + case SOCKET_URING_OP_GETSOCKNAME: + return io_uring_cmd_getsockname(sock, cmd, issue_flags); default: return -EOPNOTSUPP; } -- 2.51.0 ^ permalink raw reply related [flat|nested] 8+ messages in thread
end of thread, other threads:[~2025-11-22 2:16 UTC | newest] Thread overview: 8+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2025-11-21 16:09 [PATCH RESEND v2 0/3] Introduce getsockname io_uring_cmd Gabriel Krisman Bertazi 2025-11-21 16:09 ` [PATCH v2 1/3] socket: Unify getsockname and getpeername implementation Gabriel Krisman Bertazi 2025-11-22 1:20 ` Jakub Kicinski 2025-11-22 2:14 ` Kuniyuki Iwashima 2025-11-21 16:09 ` [PATCH v2 2/3] socket: Split out a getsockname helper for io_uring Gabriel Krisman Bertazi 2025-11-22 2:15 ` Kuniyuki Iwashima 2025-11-21 16:09 ` [PATCH v2 3/3] io_uring: Introduce getsockname io_uring cmd Gabriel Krisman Bertazi -- strict thread matches above, loose matches on Subject: below -- 2025-11-20 21:58 [PATCH v2 0/3] Introduce getsockname io_uring_cmd Gabriel Krisman Bertazi 2025-11-20 21:58 ` [PATCH v2 3/3] io_uring: Introduce getsockname io_uring cmd Gabriel Krisman Bertazi
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox