vsock: read from socket's error queue
authorArseniy Krasnov <avkrasnov@salutedevices.com>
Tue, 10 Oct 2023 19:15:14 +0000 (22:15 +0300)
committerDavid S. Miller <davem@davemloft.net>
Sun, 15 Oct 2023 12:19:42 +0000 (13:19 +0100)
This adds handling of MSG_ERRQUEUE input flag in receive call. This flag
is used to read socket's error queue instead of data queue. Possible
scenario of error queue usage is receiving completions for transmission
with MSG_ZEROCOPY flag. This patch also adds new defines: 'SOL_VSOCK'
and 'VSOCK_RECVERR'.

Signed-off-by: Arseniy Krasnov <avkrasnov@salutedevices.com>
Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
include/linux/socket.h
include/uapi/linux/vm_sockets.h
net/vmw_vsock/af_vsock.c

index 39b74d83c7c4a7e8f1434a8b2005f0d7d8d4904f..cfcb7e2c3813f2dbd3fd5ca9d123a6883713d672 100644 (file)
@@ -383,6 +383,7 @@ struct ucred {
 #define SOL_MPTCP      284
 #define SOL_MCTP       285
 #define SOL_SMC                286
+#define SOL_VSOCK      287
 
 /* IPX options */
 #define IPX_TYPE       1
index c60ca33eac594bbed44b87ab416087090a352da9..ed07181d4eff917591dd459f4325078b33957bbe 100644 (file)
@@ -191,4 +191,21 @@ struct sockaddr_vm {
 
 #define IOCTL_VM_SOCKETS_GET_LOCAL_CID         _IO(7, 0xb9)
 
+/* MSG_ZEROCOPY notifications are encoded in the standard error format,
+ * sock_extended_err. See Documentation/networking/msg_zerocopy.rst in
+ * kernel source tree for more details.
+ */
+
+/* 'cmsg_level' field value of 'struct cmsghdr' for notification parsing
+ * when MSG_ZEROCOPY flag is used on transmissions.
+ */
+
+#define SOL_VSOCK      287
+
+/* 'cmsg_type' field value of 'struct cmsghdr' for notification parsing
+ * when MSG_ZEROCOPY flag is used on transmissions.
+ */
+
+#define VSOCK_RECVERR  1
+
 #endif /* _UAPI_VM_SOCKETS_H */
index d841f4de33b0e16cadb22c94a566cf4179fa7a77..38486efd3d05d6e98ab41bd971a3694d9d72cfbb 100644 (file)
@@ -89,6 +89,7 @@
 #include <linux/types.h>
 #include <linux/bitops.h>
 #include <linux/cred.h>
+#include <linux/errqueue.h>
 #include <linux/init.h>
 #include <linux/io.h>
 #include <linux/kernel.h>
 #include <linux/workqueue.h>
 #include <net/sock.h>
 #include <net/af_vsock.h>
+#include <uapi/linux/vm_sockets.h>
 
 static int __vsock_bind(struct sock *sk, struct sockaddr_vm *addr);
 static void vsock_sk_destruct(struct sock *sk);
@@ -2137,6 +2139,10 @@ vsock_connectible_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
        int err;
 
        sk = sock->sk;
+
+       if (unlikely(flags & MSG_ERRQUEUE))
+               return sock_recv_errqueue(sk, msg, len, SOL_VSOCK, VSOCK_RECVERR);
+
        vsk = vsock_sk(sk);
        err = 0;