From nobody Fri Oct 23 22:42:42 2026 Received: from mail-wm1-f51.google.com (mail-wm1-f51.google.com [209.85.128.51]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3F8D747986C for ; Fri, 16 Oct 2026 13:27:23 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.51 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1792157245; cv=none; b=agqWZR+Dps5XnvaVuz6Ol4Z9ipvE9FPtOXneXH0RdRwZci/ErScoQBgPaHnnXlgW9U8PAf4v/16UmOMF9FoajPyLrDPAh+xv1fv0bjLdwOUEDrHIGKYc21EVm5wDFqbBQT5GG+Z9YThbXwaMAlA71SDv8E06XmKoAoWn+ZB5Q2o= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1792157245; c=relaxed/simple; bh=7lJhbyjirH5zCJmTumSnG3oHiNd4/m1148HN9wMGhoU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=epxDxtIt9h8gT50U/SEs+32fVsG3l/CFrVJsWYyxZACzSL0hmETuGvIlgBwc5kGy+sOEkx5QsNO9y/l2YzGW8SrnVXiAa9IfxVkuiZemuEMl3LhO4fFwZXYl4NAk2DAFXYNJZJvx5dz/woBh2P9xZKX6umgVm68p+OyoOBfD27w= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=kQRilWui; arc=none smtp.client-ip=209.85.128.51 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="kQRilWui" Received: by mail-wm1-f51.google.com with SMTP id 5b1f17b1804b1-4a1698ea378so52579085e9.2 for ; Fri, 16 Oct 2026 06:27:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1792157241; x=1792762041; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=MIGsi8yoMefpYRASR5cNSIMFZDXgY+eEY8Ausj37ByM=; b=kQRilWuiAn8tICLJUeOY3AAv29cxLQwuRgfsTvX/wPX5TQD7xVoZlr64wNK8Dy0xHP 27Cqrj2iL4lro2KEGHRkdixM/9hbqfyQtW75865l7yFti57Q00cLub58zNyh5gkhaROl WeuLhJ2aZTX/P1N84tBXCP7DToZeekNGDXGXISemMuqeJvWqBWn4+nkDJ1nmUdvQ6du6 tgMuXLxFpbIFUQwOE3QLZD2J+AQbjtKFl8qB9B7DG+QeiDJE1G+D2r0V+vrllIRT6GoN esYt5nA4thMexChiZECyCayUu4pfVNA0uqoRP3xowuxiDIFYTsWIOkBk6TxmjWM4Gr+W MdBw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1792157241; x=1792762041; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=MIGsi8yoMefpYRASR5cNSIMFZDXgY+eEY8Ausj37ByM=; b=Oc5Jv63KGETw03zkaEFpCvJg31FAU/fOYUKuAl5uWDbDaA2wwl2RKXzE+YBemxuHzN L5Dt25dgu02b0S4wydjs5/CRTBbXNKrk/JjH9hSJXotXi0uwwWZhb0rpVfzmAhbGnEPe J56mdFntDg3sIIukAEFUmpfsyH0MZ+yFqG0gfGiYMuOUv96dOTM5hwGyn+c5mHfYFYRR /fo9765Ssr8dxZSFNeYBY8BM4sJdf/LrSYX9oWh7Ha7bzJQX7Fniy95WX2DK32pUgOBk KUM8h2Ctff836Knve7QarpebRY2pvluIyZvapEeWyF1pRQQxTvYz+1WOcyZfRvbPKbIp K/pw== X-Forwarded-Encrypted: i=1; AKwUvByzMuzUV3jLXvvS7urLc0jDyK12eS5qgvtTqRtMTieYKv7LgApY23a3ZR9ppOuMcyZoDKC94gt1dwfglC4=@vger.kernel.org X-Gm-Message-State: AFq9FYKSQZVchUkOzry7o4lJlm30wdP8EkmLMRcS+6QdXqjvAZyAFQNM DptaPiKsHflzPyR4p5uzouR7D7d5Vd8zKFgmiKS0Tki6ZXF8bJpVayVJ X-Gm-Gg: AYBFou37CiZPNubm3hss1qg4E5addIE/71Lj+sMJ6AKjTa9caIlmaDF+do5SayBSU2Q aI3Nn7S9ZXKDQ+MFZJo733E7WdGGVk9/zHjDNHzksf3PtnZJm+MWsBfADRmCKY2Y9OPC7w2Ghe4 1XSN13svD3k6l46HIgZuxXJ/ddKIf7/5aLDXHkx04Khyh8i03zVqdjvtavn6HTClwotLSrNRFRh Pl8T88vDeZkq8Fh00OiSVPn+taH1gZ60tILJXsG+ElSlHWrybVpbTWp5tHAIsp+pwFUoamLZw+g n2oOS8AP69wmrKHPrAMuGs1ShEq9gBPHRueiWJbSxbvb02No4Fy0ATmwdAx+0CcBcT9gWmbLCCj TjjpF6sNEApPjyRt/BzkuerBPDkdBcnqkcNb4/VJ71Oo1IKz1hqhYpJGqaw76Uk2s1sOE1zKM0M n4/er0dV1TxhOmkzK/6MuY8jMwG6hzCDXpPNSP+opyxtd7LrO8QP7FItUNTG3NDKs8i/KvFBnrM M8nOl7q1Edc5a/zr9xAFk0EUTHou+YymM+5JZq+4QsHL6szmQXIqGa/JCA= X-Received: by 2002:a05:600c:3e0f:b0:4a0:1b21:2628 with SMTP id 5b1f17b1804b1-4a18e4b60d8mr444663565e9.23.1792157241254; Fri, 16 Oct 2026 06:27:21 -0700 (PDT) Received: from dohko.chello.ie (188-141-5-72.dynamic.upc.ie. [188.141.5.72]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-4a1c8de7230sm58114275e9.14.2026.10.16.06.27.20 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 16 Oct 2026 06:27:20 -0700 (PDT) From: David Carlier To: netdev@vger.kernel.org Cc: sgarzare@redhat.com, bobbyeshleman@gmail.com, davem@davemloft.net, edumazet@kernel.org, kuba@kernel.org, pabeni@redhat.com, horms@kernel.org, virtualization@lists.linux.dev, linux-kernel@vger.kernel.org, David Carlier Subject: [PATCH net-next v3 1/3] vsock: move SOL_SOCKET options to vsock_sol_socket_setsockopt() Date: Fri, 16 Oct 2026 14:27:14 +0100 Message-ID: <20261016132716.272018-2-devnexen@gmail.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20261016132716.272018-1-devnexen@gmail.com> References: <20261016132716.272018-1-devnexen@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" SO_ZEROCOPY is handled inline in vsock_connectible_setsockopt(). Move it to a helper with a switch on optname, so other SOL_SOCKET options can be added as new cases. The value parsing goes to its own helper too, so each option can do its own checks before it. No functional change. Signed-off-by: David Carlier Reviewed-by: Stefano Garzarella --- net/vmw_vsock/af_vsock.c | 90 +++++++++++++++++++++++++++++----------- 1 file changed, 65 insertions(+), 25 deletions(-) diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c index 1c2d1cea67f4..ac2faac97462 100644 --- a/net/vmw_vsock/af_vsock.c +++ b/net/vmw_vsock/af_vsock.c @@ -2014,6 +2014,66 @@ static void vsock_update_buffer_size(struct vsock_so= ck *vsk, vsk->buffer_size =3D val; } =20 +static bool vsock_sol_socket_custom(int optname) +{ + switch (optname) { + case SO_ZEROCOPY: + return true; + default: + return false; + } +} + +static int vsock_sol_socket_get_bool(sockptr_t optval, unsigned int optlen, + int *val) +{ + /* Use 'int' type here, because variable to set these options usually + * has this type. + */ + if (optlen < sizeof(*val)) + return -EINVAL; + + if (copy_from_sockptr(val, optval, sizeof(*val))) + return -EFAULT; + + if (*val < 0 || *val > 1) + return -EINVAL; + + return 0; +} + +static int vsock_sol_socket_setsockopt(struct sock *sk, int optname, + sockptr_t optval, unsigned int optlen) +{ + struct vsock_sock *vsk =3D vsock_sk(sk); + int err; + int val; + + lock_sock(sk); + + switch (optname) { + case SO_ZEROCOPY: + err =3D vsock_sol_socket_get_bool(optval, optlen, &val); + if (err) + break; + + if (vsk->transport && !vsock_msgzerocopy_allow(vsk->transport)) { + err =3D -EOPNOTSUPP; + break; + } + + sock_valbool_flag(sk, SOCK_ZEROCOPY, val); + break; + + default: + err =3D -ENOPROTOOPT; + break; + } + + release_sock(sk); + return err; +} + static int vsock_connectible_setsockopt(struct socket *sock, int level, int optname, @@ -2045,36 +2105,16 @@ static int vsock_connectible_setsockopt(struct sock= et *sock, sk =3D sock->sk; vsk =3D vsock_sk(sk); =20 - lock_sock(sk); - - transport =3D vsk->transport; - if (level =3D=3D SOL_SOCKET) { - int zerocopy; - - if (optname !=3D SO_ZEROCOPY) { - release_sock(sk); + if (!vsock_sol_socket_custom(optname)) return sock_setsockopt(sock, level, optname, optval, optlen); - } - - /* Use 'int' type here, because variable to - * set this option usually has this type. - */ - COPY_IN(zerocopy); =20 - if (zerocopy < 0 || zerocopy > 1) { - err =3D -EINVAL; - goto exit; - } + return vsock_sol_socket_setsockopt(sk, optname, optval, optlen); + } =20 - if (transport && !vsock_msgzerocopy_allow(transport)) { - err =3D -EOPNOTSUPP; - goto exit; - } + lock_sock(sk); =20 - sock_valbool_flag(sk, SOCK_ZEROCOPY, zerocopy); - goto exit; - } + transport =3D vsk->transport; =20 switch (optname) { case SO_VM_SOCKETS_BUFFER_SIZE: --=20 2.55.0 From nobody Fri Oct 23 22:42:42 2026 Received: from mail-wm1-f43.google.com (mail-wm1-f43.google.com [209.85.128.43]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 99E764C9E18 for ; Fri, 16 Oct 2026 13:27:24 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.43 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1792157246; cv=none; b=mlusdToM746LL7gRbDYyHLunRh1bZHq2Dt69Aw3WodVoJJH5GNj4h5O9YNNm2pTBFAk9ztzxPPGQKNOrXSGfrIqgpYG2rBs3jkgT7RvzsiMPJtiTm3Q+uH4Xzy2D5PHzaQjOKrG0acHMV6sYkBim6Sj6aaLwUTi2sPXq3LM5XXc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1792157246; c=relaxed/simple; bh=ISWeu8QEzSrFqiBXeb7EFy71sqAccupUyBleU+xH4Zo=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=U3HmInbmbuvbQQ/wvyL/5GZMuy3r8ttWB+ifrQ9DJA3jpVXXFjYLYrjvXVgXHthhGWIKZdU/+brbQ1+FG4+iKQYZ7KYKdLpbKwFXPeoqeI3Wgb215iQAYKCLUGtXlToQZHTVntckcFfm7Ye8+bHjbP/llLl3PVP5LDWxWq5oHXI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=WG5h5/JJ; arc=none smtp.client-ip=209.85.128.43 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="WG5h5/JJ" Received: by mail-wm1-f43.google.com with SMTP id 5b1f17b1804b1-49d0da752ffso26133565e9.3 for ; Fri, 16 Oct 2026 06:27:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1792157243; x=1792762043; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=4YjOyRguzbQ9PKrv92k4FnDoKt53mMLhByiAMojhitA=; b=WG5h5/JJbmwsFmMPsBjmviIYBhCdOPPBRYKcYpNCW6ZV8W6XUgABurQJibcep0nav3 eZqF2qxdOeOBomRfLo+0sbJZK20uIaNKhzy3yurarahQhS/KklXbNLOQsRUt4ndsdeY+ pPndUUa9JWf2rAsqDgafX6aFrCBpg8RjhlPEJ+Mw92pgXlpiLJsQIWDmifOxaTKMgmYW ItJbqDEpI4TK0qAuXhgijkEHDywWghWiYUCRri3Jq2XffrsN2Jl6xYyv9rBSHGRkYlDm D1WhBy5v9WiMuZVUFqx+Qaxmg8WhnsMmfcuH2FrqRvm0oUfQh51ff1NHmNHLb6s7EDl4 iwRQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1792157243; x=1792762043; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=4YjOyRguzbQ9PKrv92k4FnDoKt53mMLhByiAMojhitA=; b=CWOY71f/7Oere8hyNpI3UY162ACdTLHSPhtlr2OY6ZCctksp6bcf5hOwQjXcVOWEmv p22cqjwNeHP4pbr68suPU62YKjZe6wg08Oi9eGzL5Ne9574v0byVE8zt3lk5Hhl6ZWl/ Xi/hZj7CzRLZYA4YcsV/TsTjtmiz+9MoMW7qrfc0hZpdim06is3Tzao10fBR5ptrdnJy gFZXdnRhGn8r2PjRB/cr+/1zBJwvIujXFFjOasYlTEzuwiTkIOrORqgHVYnj3Pt+96o+ jAB6AQ0zHb+P0uqhiLxWtgu1iYEAoOt8ZFeSv2pfFYXvuVlAFKRHYxckvEF/cumDb4lV VXBg== X-Forwarded-Encrypted: i=1; AKwUvBxb3Ux5jhR7iKbBvY9nfNyRJaUQ1fpWmHrpXGZEi0KGgbgBEZTZcoJWtylSR7JC5z7b6lb2PiKhvPpFX4k=@vger.kernel.org X-Gm-Message-State: AFq9FYKQTbhNpLxAs+rhgkSzYjoJEL7BJ0NoS7Z0Fb+60xfe966epzFN DaVEHebW5VK6/GgQBlZlqe9XUaZk5vTxFYMCcpf42Vs3wReYFgT4njLW X-Gm-Gg: AYBFou35uj6jY4bK0ygL2mwZ++utNYWk1yS9PjAEGx3NUPCduinJT/WwVfQ5XewfBOL 8eiG0b5YOBHzwUvqP/NrI3zJPmLnFGW+nVTRI820w7KRVGY/Jd/ZLHipVvnSYVt+HPjsgjutooO CI0pxcyOHeX8fcRz4jxvy9F6codG+jcVCTRdsJ4POp9gf5DaBhpK4XecEuhA16cURm/49/wuRY2 wQkQzdmdgnJdB8TMt4SPZhxuClWEt8BJlfwDKa8msRX7Ej99lolGX3NXT/oKxC2o+5xUW4nuLeY tZVmzXrDwlufKn3kahi+qrDrhjYFRpxyHGvM3iKJRrvYlY36wckuezV3PMG3LadmeSTE9oAeoiE 7H9ii8sEDxW3UGlmnadNfdUN3dNBX1ZqvGPGlz9AKeeOLnI71teGeEJEdhE3WIcuQT6ewIw56JZ VQnK2BxT1NAqS6dl3UqVgscPmzn2LNDJ3TBNBg11uG/xyZ+zDPUBirZBXtdoojw07Dtbx07aDw+ vy0tT2W8NVD7UmK5ckxgSDyce7i6Y0pOXnaJJH/aFngQlQC2gW9FaLGDjQ= X-Received: by 2002:a05:600c:3e87:b0:4a0:a34:6e7d with SMTP id 5b1f17b1804b1-4a18e4bacbfmr418899375e9.18.1792157242302; Fri, 16 Oct 2026 06:27:22 -0700 (PDT) Received: from dohko.chello.ie (188-141-5-72.dynamic.upc.ie. [188.141.5.72]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-4a1c8de7230sm58114275e9.14.2026.10.16.06.27.21 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 16 Oct 2026 06:27:21 -0700 (PDT) From: David Carlier To: netdev@vger.kernel.org Cc: sgarzare@redhat.com, bobbyeshleman@gmail.com, davem@davemloft.net, edumazet@kernel.org, kuba@kernel.org, pabeni@redhat.com, horms@kernel.org, virtualization@lists.linux.dev, linux-kernel@vger.kernel.org, David Carlier Subject: [PATCH net-next v3 2/3] vsock: support SO_INQ on stream sockets Date: Fri, 16 Oct 2026 14:27:15 +0100 Message-ID: <20261016132716.272018-3-devnexen@gmail.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20261016132716.272018-1-devnexen@gmail.com> References: <20261016132716.272018-1-devnexen@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" SO_INQ makes recvmsg() return the bytes left in the receive queue in an SCM_INQ cmsg, saving a SIOCINQ call per receive. AF_UNIX stream sockets support it, AF_VSOCK fails with ENOPROTOOPT. Add it for SOCK_STREAM, reusing the hint already computed for io_uring. As with TCP_INQ, 1 is reported once the stream is finished so the caller reads again and sees EOF, and accepted sockets inherit the setting from the listener. No cmsg is sent when the transport cannot report the queue length. SOCK_SEQPACKET is refused, as on AF_UNIX: its transport callback counts messages, not bytes. Signed-off-by: David Carlier Reviewed-by: Stefano Garzarella --- include/net/af_vsock.h | 1 + net/vmw_vsock/af_vsock.c | 35 ++++++++++++++++++++++++++++++++--- 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/include/net/af_vsock.h b/include/net/af_vsock.h index 5549298c1ec6..e8481f12312e 100644 --- a/include/net/af_vsock.h +++ b/include/net/af_vsock.h @@ -68,6 +68,7 @@ struct vsock_sock { u64 buffer_size; u64 buffer_min_size; u64 buffer_max_size; + bool recvmsg_inq; =20 /* Private to transport. */ void *trans; diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c index ac2faac97462..6d77e6344840 100644 --- a/net/vmw_vsock/af_vsock.c +++ b/net/vmw_vsock/af_vsock.c @@ -984,6 +984,7 @@ static struct sock *__vsock_create(struct net *net, vsk->buffer_size =3D psk->buffer_size; vsk->buffer_min_size =3D psk->buffer_min_size; vsk->buffer_max_size =3D psk->buffer_max_size; + vsk->recvmsg_inq =3D psk->recvmsg_inq; security_sk_clone(parent, sk); } else { vsk->trusted =3D ns_capable_noaudit(&init_user_ns, CAP_NET_ADMIN); @@ -2018,6 +2019,7 @@ static bool vsock_sol_socket_custom(int optname) { switch (optname) { case SO_ZEROCOPY: + case SO_INQ: return true; default: return false; @@ -2065,6 +2067,19 @@ static int vsock_sol_socket_setsockopt(struct sock *= sk, int optname, sock_valbool_flag(sk, SOCK_ZEROCOPY, val); break; =20 + case SO_INQ: + if (sk->sk_type !=3D SOCK_STREAM) { + err =3D -ENOPROTOOPT; + break; + } + + err =3D vsock_sol_socket_get_bool(optval, optlen, &val); + if (err) + break; + + vsk->recvmsg_inq =3D val; + break; + default: err =3D -ENOPROTOOPT; break; @@ -2621,6 +2636,7 @@ __vsock_connectible_recvmsg(struct socket *sock, stru= ct msghdr *msg, size_t len, struct sock *sk; struct vsock_sock *vsk; const struct vsock_transport *transport; + bool do_cmsg =3D false; int err; =20 sk =3D sock->sk; @@ -2677,13 +2693,26 @@ __vsock_connectible_recvmsg(struct socket *sock, st= ruct msghdr *msg, size_t len, err =3D __vsock_seqpacket_recvmsg(sk, msg, len, flags); =20 out: - /* Seqpacket has_data counts messages, while io_uring treats msg_inq as - * a byte length when sizing retries, so only streams report a hint. + /* Seqpacket has_data counts messages, while SCM_INQ reports bytes and + * io_uring treats msg_inq as a byte length when sizing retries, so + * only streams report it. */ - if (msg->msg_get_inq && err >=3D 0 && sk->sk_type =3D=3D SOCK_STREAM) + if ((vsk->recvmsg_inq || msg->msg_get_inq) && err >=3D 0 && + sk->sk_type =3D=3D SOCK_STREAM) { msg->msg_inq =3D vsock_stream_inq_hint(sk); =20 + /* A negative hint means the transport could not tell. SCM_INQ + * has no encoding for that, so report nothing. + */ + do_cmsg =3D vsk->recvmsg_inq && msg->msg_inq >=3D 0; + } + release_sock(sk); + + if (do_cmsg) + put_cmsg(msg, SOL_SOCKET, SCM_INQ, sizeof(msg->msg_inq), + &msg->msg_inq); + return err; } =20 --=20 2.55.0 From nobody Fri Oct 23 22:42:42 2026 Received: from mail-wm1-f50.google.com (mail-wm1-f50.google.com [209.85.128.50]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 844384CDDC2 for ; Fri, 16 Oct 2026 13:27:25 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.50 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1792157247; cv=none; b=kynzAFzdYJn5V/5QatRJxw1ZiEzyb3mclbzuFNxj3rJLS7jvtW4BsNOS1pDWyFCOQnd6+C+ozsmLSdTj0QZSXEUjr9tS0bjOMyDK6IGqeZHYho2KWjsMQPWgC5kdWd3fkGMn2QQo+lemi6TFiiRYvHHzLqKjaJuuP8dKGymwCwQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1792157247; c=relaxed/simple; bh=hLVvPaADOzHjxZw4TUN3HlFoVzI8Xz1/lEUKmQN+0+g=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=n1zm6obiOwXCxYQaXrKdSzdetp9yRcKidFYvlour4Khkfz0enjeph9iio13X9zFqmmWZWX7NGjehOkM4qeHeQ8cXCxxhRe1UCPxQOE8YAXmZ/9ZLejzx6cjTGTY6cVjehhrOXdCg1Eld9+T/f3oCsBv1l0TDGdNZMZp4Z5XCZ1I= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=Lw+eE3LK; arc=none smtp.client-ip=209.85.128.50 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="Lw+eE3LK" Received: by mail-wm1-f50.google.com with SMTP id 5b1f17b1804b1-4a16aaf2067so39009815e9.0 for ; Fri, 16 Oct 2026 06:27:25 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1792157244; x=1792762044; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=ABUldiMgqEkToVfvm0gRz1JDqAgP1R8x5uZIM0eMbNU=; b=Lw+eE3LKJnCYEanZImuVydnNlqzWnDx/Fs+zQ72huOmxHRoCPG46EKzgbhCBtfjXEL JF6NgWu/hVeNgk+ARY4zm0vkVKX8iYDrrUBcxCl98W+2+keT0o+7MXrScpf0KIAOyqKC p3Uo1BBkSxzqbwckBBGYc7V3Hej0WErd+pkptn48o+asFQnozYnN1jSdzH+dwK8gaVJd T/qkNSGR7yQotFzMy7DyRDoK0BtI2kuZ+UmhLsWTCKFFOUuFQKcI7WaNY4o2LuRbbYnQ b0UDGQ4fcafcbLkjbPhdM4CSMP5VupZwdKbhrNdSkgsaMioy83S9KiAo66xeExdgpXp3 ZKqg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1792157244; x=1792762044; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=ABUldiMgqEkToVfvm0gRz1JDqAgP1R8x5uZIM0eMbNU=; b=ZbL1CtYTMra2Jl4ctuE1x9PbjE9I4lK7e9ydPySuucQX843CI9JlcuFWlIE5aimVNB ciaQUdfuKfHoBavh3fP21AMKb6eBy6cPA4fAlf2aeAHWBHKguNOcAAb8q58xV9TgFfD6 Ip3+NzYy6EM0FrISep/BErvrf4cdqo0WWJYXquwwYDRGikqN5Er7cZSZPo6zkGYIgqea LqXcepwe7uENh8tQKeymM4ysU+eKrCExwoOhV7sHg5VfQKaGH2qQbsIaE8xAMdoBcdsG 8y4oDsodyJPyL7xK48tT7MyBDA99X5NiZR+1yGtvO4UBCMkn2+YjQU0lbQtA5i1Dsf2B QtjQ== X-Forwarded-Encrypted: i=1; AKwUvBx9rEH6pBgbn+h5Zp8MvCgI9V6273rkqpIEp9IXeGpJ6hSChB6/gsabbXZzWjc6GxYhH6ys2P50KsazxxA=@vger.kernel.org X-Gm-Message-State: AFq9FYIn7aR/bGAoHnM3ptYGtEDm+Oy6yizG1pRAxYeNrOiS4N8fhRkk EXo1K9VkWEjfr71ua2GESL5igXly/o5jBjLmFMGXyIiq0AT0gux/ZmGy X-Gm-Gg: AYBFou1oiUHjgHee8C6fTnVJWA996BVnF11hBI3+iHn8U74K6Qt56rkd21ISRZdtLmj U4JOeXWFWUKmta9s1A627t5WUs/P+l2NigQGG3LgqduJJMAPDVYF1XhvNbS6pp7gWVa6JXo+zT/ wVblirAtJMJc9TDeJFkFGVTNPePaVvXhyr64S+3YXOWB+1yEsCqdg8+D5SXhJvbI6Y4+6puf/IZ gJgft1MbDKOViLbfLcKo47O072iJG+1r/SbAxgLeMb5t8MXSMuPdIgvXOjBbiWI//Z2CvDT7KDA SQlN3jmXA9Wk08pdBsgSG3TynKzAk9j4QKdk5PLm53cNrt7THJeF09F08UNA3HrtqdM6JhNr2G/ 2VkFfyGsdJVJ6xNUC3GuEQ67Ck4AH0sOFW03/xHqBsToQADhvD+bYMxwNMCcgg1TjkP/EEpAJ4v KAq7LOsk4rfz/RS9nYenXkV8KcjlzQdpf7DVsKAaQ5Mxxl1HP2q3pnCNEwxdOVhI62R1aJcxd+U nHw7YYiPUax6g3yK00f1TwlUniAMhnFNhayCHuUlWAwqmIw/BTeKVMS1QQ= X-Received: by 2002:a05:600c:3b02:b0:4a1:cdd1:5144 with SMTP id 5b1f17b1804b1-4a1cdd15182mr34872015e9.21.1792157243530; Fri, 16 Oct 2026 06:27:23 -0700 (PDT) Received: from dohko.chello.ie (188-141-5-72.dynamic.upc.ie. [188.141.5.72]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-4a1c8de7230sm58114275e9.14.2026.10.16.06.27.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 16 Oct 2026 06:27:23 -0700 (PDT) From: David Carlier To: netdev@vger.kernel.org Cc: sgarzare@redhat.com, bobbyeshleman@gmail.com, davem@davemloft.net, edumazet@kernel.org, kuba@kernel.org, pabeni@redhat.com, horms@kernel.org, virtualization@lists.linux.dev, linux-kernel@vger.kernel.org, David Carlier , Bobby Eshleman Subject: [PATCH net-next v3 3/3] vsock/test: cover SO_INQ Date: Fri, 16 Oct 2026 14:27:16 +0100 Message-ID: <20261016132716.272018-4-devnexen@gmail.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20261016132716.272018-1-devnexen@gmail.com> References: <20261016132716.272018-1-devnexen@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Check the SCM_INQ value after a partial receive, after draining the queue and at EOF, that no cmsg is sent while the option is off, that accepted sockets inherit it from the listener, and that out of range values and SOCK_SEQPACKET are rejected. Reviewed-by: Stefano Garzarella Acked-by: Bobby Eshleman Signed-off-by: David Carlier --- tools/testing/vsock/vsock_test.c | 279 +++++++++++++++++++++++++++++++ 1 file changed, 279 insertions(+) diff --git a/tools/testing/vsock/vsock_test.c b/tools/testing/vsock/vsock_t= est.c index b4ff9f946565..10b9074fb87f 100644 --- a/tools/testing/vsock/vsock_test.c +++ b/tools/testing/vsock/vsock_test.c @@ -2429,6 +2429,271 @@ static void test_stream_collapse_server(const struc= t test_opts *opts) close(fd); } =20 +#define SO_INQ_BUF_LEN 64 +#define SO_INQ_CHUNK_LEN 16 + +static int so_inq_set(int fd, int val) +{ + return setsockopt(fd, SOL_SOCKET, SO_INQ, &val, sizeof(val)); +} + +/* Receive @len bytes and return the SCM_INQ value, or -1 if the kernel did + * not attach one. + */ +static int so_inq_recv(int fd, size_t len, int expected_ret) +{ + char control[CMSG_SPACE(sizeof(int))] =3D { 0 }; + unsigned char buf[SO_INQ_BUF_LEN]; + struct iovec iov =3D { + .iov_base =3D buf, + .iov_len =3D len, + }; + struct msghdr msg =3D { + .msg_iov =3D &iov, + .msg_iovlen =3D 1, + .msg_control =3D control, + .msg_controllen =3D sizeof(control), + }; + struct cmsghdr *cmsg; + ssize_t ret; + int inq; + + ret =3D recvmsg(fd, &msg, 0); + if (ret < 0) { + perror("recvmsg"); + exit(EXIT_FAILURE); + } + + expect_res(ret, expected_ret, "recvmsg"); + + if (msg.msg_flags & MSG_CTRUNC) { + fprintf(stderr, "SCM_INQ control message truncated\n"); + exit(EXIT_FAILURE); + } + + for (cmsg =3D CMSG_FIRSTHDR(&msg); cmsg; cmsg =3D CMSG_NXTHDR(&msg, cmsg)= ) { + if (cmsg->cmsg_level !=3D SOL_SOCKET || + cmsg->cmsg_type !=3D SCM_INQ) + continue; + + if (cmsg->cmsg_len !=3D CMSG_LEN(sizeof(inq))) { + fprintf(stderr, "unexpected SCM_INQ length %zu\n", + (size_t)cmsg->cmsg_len); + exit(EXIT_FAILURE); + } + + memcpy(&inq, CMSG_DATA(cmsg), sizeof(inq)); + return inq; + } + + return -1; +} + +static void test_stream_so_inq_client(const struct test_opts *opts) +{ + int fd; + + fd =3D vsock_stream_connect(opts->peer_cid, opts->peer_port); + if (fd < 0) { + perror("connect"); + exit(EXIT_FAILURE); + } + + control_expectln("SENT"); + + /* Wait for the whole payload to be queued, so the values below do not + * depend on how the transport delivers it. + */ + if (!vsock_ioctl_int(fd, SIOCINQ, SO_INQ_BUF_LEN)) { + fprintf(stderr, "Test skipped, SIOCINQ not supported.\n"); + goto out; + } + + /* No ancillary data unless the option is enabled. */ + expect_res(so_inq_recv(fd, SO_INQ_CHUNK_LEN, SO_INQ_CHUNK_LEN), -1, + "SCM_INQ with SO_INQ disabled"); + + if (so_inq_set(fd, 1)) { + if (errno !=3D ENOPROTOOPT) { + perror("setsockopt(SO_INQ)"); + exit(EXIT_FAILURE); + } + + fprintf(stderr, "Test skipped, SO_INQ not supported.\n"); + goto out; + } + + /* Partial read: the rest of the payload is still queued. */ + expect_res(so_inq_recv(fd, SO_INQ_CHUNK_LEN, SO_INQ_CHUNK_LEN), + SO_INQ_BUF_LEN - 2 * SO_INQ_CHUNK_LEN, + "SCM_INQ after partial receive"); + + /* Draining read while the peer stays connected. */ + expect_res(so_inq_recv(fd, SO_INQ_BUF_LEN - 2 * SO_INQ_CHUNK_LEN, + SO_INQ_BUF_LEN - 2 * SO_INQ_CHUNK_LEN), 0, + "SCM_INQ after draining receive"); + + control_writeln("DRAINED"); + vsock_wait_remote_close(fd); + + /* Nothing is queued once the peer is gone, but 1 is reported so the + * caller keeps reading until it observes EOF, as TCP_INQ does. + */ + expect_res(so_inq_recv(fd, SO_INQ_CHUNK_LEN, 0), 1, "SCM_INQ at EOF"); + + if (so_inq_set(fd, 0)) { + perror("setsockopt(SO_INQ)"); + exit(EXIT_FAILURE); + } + + expect_res(so_inq_recv(fd, SO_INQ_CHUNK_LEN, 0), -1, + "SCM_INQ after disabling SO_INQ"); + + close(fd); + return; + +out: + control_writeln("DRAINED"); + close(fd); +} + +static void test_stream_so_inq_server(const struct test_opts *opts) +{ + unsigned char buf[SO_INQ_BUF_LEN]; + int fd; + + fd =3D vsock_stream_accept(VMADDR_CID_ANY, opts->peer_port, NULL); + if (fd < 0) { + perror("accept"); + exit(EXIT_FAILURE); + } + + memset(buf, 'A', sizeof(buf)); + send_buf(fd, buf, sizeof(buf), 0, sizeof(buf)); + control_writeln("SENT"); + + /* Keep the connection open until the peer has drained the queue: an + * early close would turn its last SCM_INQ value into the EOF one. + */ + control_expectln("DRAINED"); + close(fd); +} + +static void test_stream_so_inq_inherit_client(const struct test_opts *opts) +{ + unsigned char buf[SO_INQ_BUF_LEN]; + int fd; + + fd =3D vsock_stream_connect(opts->peer_cid, opts->peer_port); + if (fd < 0) { + perror("connect"); + exit(EXIT_FAILURE); + } + + memset(buf, 'A', sizeof(buf)); + send_buf(fd, buf, sizeof(buf), 0, sizeof(buf)); + control_writeln("SENT"); + + control_expectln("DONE"); + close(fd); +} + +static void test_stream_so_inq_inherit_server(const struct test_opts *opts) +{ + bool supported =3D true; + int listen_fd, fd; + + listen_fd =3D vsock_stream_listen(VMADDR_CID_ANY, opts->peer_port); + + /* Enable the option on the listener only. */ + if (so_inq_set(listen_fd, 1)) { + if (errno !=3D ENOPROTOOPT) { + perror("setsockopt(SO_INQ)"); + exit(EXIT_FAILURE); + } + + fprintf(stderr, "Test skipped, SO_INQ not supported.\n"); + supported =3D false; + } + + control_writeln("LISTENING"); + + timeout_begin(TIMEOUT); + do { + fd =3D accept(listen_fd, NULL, NULL); + timeout_check("accept"); + } while (fd < 0 && errno =3D=3D EINTR); + timeout_end(); + + if (fd < 0) { + perror("accept"); + exit(EXIT_FAILURE); + } + + close(listen_fd); + control_expectln("SENT"); + + if (!supported) + goto out; + + if (!vsock_ioctl_int(fd, SIOCINQ, SO_INQ_BUF_LEN)) { + fprintf(stderr, "Test skipped, SIOCINQ not supported.\n"); + goto out; + } + + /* The accepted socket reports SCM_INQ without its own setsockopt(). */ + expect_res(so_inq_recv(fd, SO_INQ_CHUNK_LEN, SO_INQ_CHUNK_LEN), + SO_INQ_BUF_LEN - SO_INQ_CHUNK_LEN, + "SCM_INQ inherited from the listener"); + +out: + control_writeln("DONE"); + close(fd); +} + +static void test_so_inq_validation_client(const struct test_opts *opts) +{ + int fd; + + fd =3D socket(AF_VSOCK, SOCK_STREAM, 0); + if (fd < 0) { + perror("socket"); + exit(EXIT_FAILURE); + } + + if (so_inq_set(fd, 1)) { + if (errno !=3D ENOPROTOOPT) { + perror("setsockopt(SO_INQ)"); + exit(EXIT_FAILURE); + } + + fprintf(stderr, "Test skipped, SO_INQ not supported.\n"); + close(fd); + return; + } + + if (!so_inq_set(fd, 2) || errno !=3D EINVAL) { + fprintf(stderr, "SO_INQ accepted an out of range value\n"); + exit(EXIT_FAILURE); + } + + close(fd); + + /* SCM_INQ counts bytes, which a message based socket cannot report. */ + fd =3D socket(AF_VSOCK, SOCK_SEQPACKET, 0); + if (fd < 0) { + perror("socket"); + exit(EXIT_FAILURE); + } + + if (!so_inq_set(fd, 1) || errno !=3D ENOPROTOOPT) { + fprintf(stderr, "SO_INQ not rejected on SOCK_SEQPACKET\n"); + exit(EXIT_FAILURE); + } + + close(fd); +} + static struct test_case test_cases[] =3D { { .name =3D "SOCK_STREAM connection reset", @@ -2633,6 +2898,20 @@ static struct test_case test_cases[] =3D { .run_client =3D test_stream_collapse_client, .run_server =3D test_stream_collapse_server, }, + { + .name =3D "SOCK_STREAM SO_INQ functionality", + .run_client =3D test_stream_so_inq_client, + .run_server =3D test_stream_so_inq_server, + }, + { + .name =3D "SOCK_STREAM SO_INQ inherited by accepted socket", + .run_client =3D test_stream_so_inq_inherit_client, + .run_server =3D test_stream_so_inq_inherit_server, + }, + { + .name =3D "SO_INQ option validation", + .run_client =3D test_so_inq_validation_client, + }, {}, }; =20 --=20 2.55.0