This adds handling of MSG_ERRQUEUE input flag for receive call, thus skb from socket's error queue is read. Signed-off-by: Arseniy Krasnov <AVKrasnov@xxxxxxxxxxxxxx> --- include/linux/socket.h | 1 + net/vmw_vsock/af_vsock.c | 26 ++++++++++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/include/linux/socket.h b/include/linux/socket.h index 13c3a237b9c9..19a6f39fa014 100644 --- a/include/linux/socket.h +++ b/include/linux/socket.h @@ -379,6 +379,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 diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c index b5e51ef4a74c..f752b30b71d6 100644 --- a/net/vmw_vsock/af_vsock.c +++ b/net/vmw_vsock/af_vsock.c @@ -110,6 +110,7 @@ #include <linux/workqueue.h> #include <net/sock.h> #include <net/af_vsock.h> +#include <linux/errqueue.h> static int __vsock_bind(struct sock *sk, struct sockaddr_vm *addr); static void vsock_sk_destruct(struct sock *sk); @@ -2086,6 +2087,27 @@ static int __vsock_seqpacket_recvmsg(struct sock *sk, struct msghdr *msg, return err; } +static int vsock_err_recvmsg(struct sock *sk, struct msghdr *msg) +{ + struct sock_extended_err *ee; + struct sk_buff *skb; + int err; + + lock_sock(sk); + skb = sock_dequeue_err_skb(sk); + release_sock(sk); + + if (!skb) + return -EAGAIN; + + ee = &SKB_EXT_ERR(skb)->ee; + err = put_cmsg(msg, SOL_VSOCK, 0, sizeof(*ee), ee); + msg->msg_flags |= MSG_ERRQUEUE; + consume_skb(skb); + + return err; +} + static int vsock_connectible_recvmsg(struct socket *sock, struct msghdr *msg, size_t len, int flags) @@ -2096,6 +2118,10 @@ vsock_connectible_recvmsg(struct socket *sock, struct msghdr *msg, size_t len, int err; sk = sock->sk; + + if (unlikely(flags & MSG_ERRQUEUE)) + return vsock_err_recvmsg(sk, msg); + vsk = vsock_sk(sk); err = 0; -- 2.25.1