]> Gentwo Git Trees - linux/.git/commitdiff
io_uring: Introduce getsockname io_uring cmd
authorGabriel Krisman Bertazi <krisman@suse.de>
Tue, 25 Nov 2025 21:18:01 +0000 (16:18 -0500)
committerJens Axboe <axboe@kernel.dk>
Wed, 26 Nov 2025 20:45:23 +0000 (13:45 -0700)
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>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
include/uapi/linux/io_uring.h
io_uring/cmd_net.c

index deb772222b6dfe4a8cb7c42241cd4c78464c3dc8..b5b23c0d5283419b77c5f3000defbc19903421bc 100644 (file)
@@ -1009,6 +1009,7 @@ enum io_uring_socket_op {
        SOCKET_URING_OP_GETSOCKOPT,
        SOCKET_URING_OP_SETSOCKOPT,
        SOCKET_URING_OP_TX_TIMESTAMP,
+       SOCKET_URING_OP_GETSOCKNAME,
 };
 
 /*
index 27a09aa4c9d0b41f797d165d99c7c8ca06c4ec9e..5d11caf5509ccc1a364644ea9b47fdc4718c3d45 100644 (file)
@@ -132,6 +132,26 @@ 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 __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, peer, 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 +179,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;
        }