[RFC v4 3/5] io/channel-socket: tolerate AF_PACKET getpeername

Cindy Lu posted 5 patches 4 days, 13 hours ago
[RFC v4 3/5] io/channel-socket: tolerate AF_PACKET getpeername
Posted by Cindy Lu 4 days, 13 hours ago
When -chardev socket,fd=... is handed an AF_PACKET socket,
getpeername() can fail with EOPNOTSUPP instead of ENOTCONN because
packet sockets are not connection-oriented. qio_channel_socket_set_fd()
currently treats that as fatal and refuses to wrap the fd, even though
getsockname() and the local address are still valid.

Treat EOPNOTSUPP the same way as ENOTCONN and leave remoteAddr empty.
That keeps existing stream-socket behavior unchanged while allowing
AF_PACKET fds to be adopted by QIOChannelSocket.

Signed-off-by: Cindy Lu <lulu@redhat.com>
---
 io/channel-socket.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/io/channel-socket.c b/io/channel-socket.c
index 3053b35ad8..2ed26aefa3 100644
--- a/io/channel-socket.c
+++ b/io/channel-socket.c
@@ -115,7 +115,11 @@ qio_channel_socket_set_fd(QIOChannelSocket *sioc,
 
     if (getpeername(fd, (struct sockaddr *)&sioc->remoteAddr,
                     &sioc->remoteAddrLen) < 0) {
-        if (errno == ENOTCONN) {
+        if (errno == ENOTCONN
+#ifdef EOPNOTSUPP
+            || errno == EOPNOTSUPP
+#endif
+            ) {
             memset(&sioc->remoteAddr, 0, sizeof(sioc->remoteAddr));
             sioc->remoteAddrLen = sizeof(sioc->remoteAddr);
         } else {
-- 
2.52.0
Re: [RFC v4 3/5] io/channel-socket: tolerate AF_PACKET getpeername
Posted by Daniel P. Berrangé 3 days, 6 hours ago
On Tue, Apr 07, 2026 at 01:05:50PM +0800, Cindy Lu wrote:
> When -chardev socket,fd=... is handed an AF_PACKET socket,
> getpeername() can fail with EOPNOTSUPP instead of ENOTCONN because
> packet sockets are not connection-oriented. qio_channel_socket_set_fd()
> currently treats that as fatal and refuses to wrap the fd, even though
> getsockname() and the local address are still valid.
> 
> Treat EOPNOTSUPP the same way as ENOTCONN and leave remoteAddr empty.
> That keeps existing stream-socket behavior unchanged while allowing
> AF_PACKET fds to be adopted by QIOChannelSocket.
> 
> Signed-off-by: Cindy Lu <lulu@redhat.com>
> ---
>  io/channel-socket.c | 6 +++++-
>  1 file changed, 5 insertions(+), 1 deletion(-)
> 
> diff --git a/io/channel-socket.c b/io/channel-socket.c
> index 3053b35ad8..2ed26aefa3 100644
> --- a/io/channel-socket.c
> +++ b/io/channel-socket.c
> @@ -115,7 +115,11 @@ qio_channel_socket_set_fd(QIOChannelSocket *sioc,
>  
>      if (getpeername(fd, (struct sockaddr *)&sioc->remoteAddr,
>                      &sioc->remoteAddrLen) < 0) {
> -        if (errno == ENOTCONN) {
> +        if (errno == ENOTCONN
> +#ifdef EOPNOTSUPP
> +            || errno == EOPNOTSUPP
> +#endif

Why conditionalize it ?  We use this unconditionally throughout
QEMU code AFAICS, even on Windows.

> +            ) {
>              memset(&sioc->remoteAddr, 0, sizeof(sioc->remoteAddr));
>              sioc->remoteAddrLen = sizeof(sioc->remoteAddr);
>          } else {
> -- 
> 2.52.0
> 
> 

With regards,
Daniel
-- 
|: https://berrange.com       ~~        https://hachyderm.io/@berrange :|
|: https://libvirt.org          ~~          https://entangle-photo.org :|
|: https://pixelfed.art/berrange   ~~    https://fstop138.berrange.com :|