From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.remote-ip=170.10.129.124 ARC-Seal: i=1; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; cv=none; t=1794590176; b=2O8QF+IF1u8l7eHBXgx4rt6wpC3f11lC9CAAaGL2AWROpdRTZDGKLrvgGWbaSyilgF8X r9EyoWPr3Pukgj3zJN6Lin9fiRguW68+pql6wuxnSOmo1E4q40SQZikHDY1Sh+zF+f4a2 sk2R2WmsBrpbIqH7M6EitB01dOr31SWh/ZooAE7n6jaDXgmbubIhD07wUlebfbZ5b5Myp Vaecq3Zymodbxby7BgynJ/QEbmibwptVfAztwVOZVyOywWX6N5DGZ2hYSSPPPrzmjOu6h IHEAy46TuUnWf4T1/ix3GO5OIWyGgoiBYewJJTpp4oeRWLt6nGtvY8HGENU29Bnc0UQ== ARC-Message-Signature: i=1; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; c=relaxed/relaxed; t=1794590176; h=DMARC-Filter:DKIM-Signature:Received:X-MC-Unique: X-Mimecast-MFC-AGG-ID:Received:DKIM-Signature:X-Google-DKIM-Signature: X-Forwarded-Encrypted:X-Gm-Message-State:X-Gm-Gg:X-Received: X-Received:Received:From:Date:Subject:MIME-Version:Content-Type: Content-Transfer-Encoding:Message-Id:References:In-Reply-To:To:Cc: X-Mailer:X-Developer-Signature:X-Developer-Key; bh=ip7OqnOPWA382+L4zd800WcdSezVmBpGTHBVFqhAjEc=; b=ahMtRGu9zHsjfCuvi0M6ewWv1t0OzZ+i5558jFywub1xooLcIUAvm9IzP15hwseLkuYk Pe+morJIjgfuGBCfi9rv1uk9hZd4nPDA/m1z1XTeGESL9IrwKXBdb3RmFBLSElP2kP/hp Iefnct7GEfnBW9d6saLsDXa6BIBG3jxghDzrVItjoi65sAg7S1AyyQ3WfBxpY1Bd28DYy 0Sr0IoDpnD+yRQyRSy1NcbsLQ8S0L1cfX5XYzRHs6dG0kgcBJMRnWlJRRNz4BI0toJH7d kdVXr8oN0DDDuHC8CVibPJ2ram+5izDqgBQ7HVL1LQlc3otJoPsC52zKuYkE18kepTA== ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=QZUnQoEJ; dkim=pass header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=google header.b=MPRQSaxV; arc=none smtp.remote-ip=170.10.129.124 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (prime256v1) server-digest SHA256) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A0BB8606A89E for ; Fri, 13 Nov 2026 17:16:15 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.2 smtp.subspace.kernel.org A0BB8606A89E Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=QZUnQoEJ; dkim=pass (2048-bit key) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=google header.b=MPRQSaxV DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1794590174; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=ip7OqnOPWA382+L4zd800WcdSezVmBpGTHBVFqhAjEc=; b=QZUnQoEJm7XQXhS2h8VI8WE/5dvirpLShw8zyd6Se3yltT3+zY6CA6Zi6n1hUCGBHfJdWv otUrXbSwemMv0ZRA4I61Mvqe3pevV5MITxBTwzmvSb/ODfzOSBnxbQxJ/bWVNFyXwsEoOz Ok4ku/MUOZPEn0r1sAU/+XZmvHlFCUE= Received: from mail-wm1-f70.google.com (mail-wm1-f70.google.com [209.85.128.70]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-225-4NU1kNl7MlypV-XrInhqOw-1; Fri, 13 Nov 2026 12:16:13 -0500 X-MC-Unique: 4NU1kNl7MlypV-XrInhqOw-1 X-Mimecast-MFC-AGG-ID: 4NU1kNl7MlypV-XrInhqOw_1794590172 Received: by mail-wm1-f70.google.com with SMTP id 5b1f17b1804b1-4b8b3cd61a5so11973185e9.1 for ; Fri, 13 Nov 2026 09:16:13 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=google; t=1794590172; x=1795194972; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=ip7OqnOPWA382+L4zd800WcdSezVmBpGTHBVFqhAjEc=; b=MPRQSaxVQ6g4n1yoozuejjLxYAlYU2iqp64bcYf49fLuKJqZeI3Zq2igWzmd83uvoa xObjuVeKK1IXbyVbsYvdETeo44g7B9zzj1dSgSRSO2FcH5+M9hmTc8lm0lpEZU3zp/MG nlNRmMdmiFI2663hwBS6gGjiTk/n5wO6xJNKSI5X15evAnH99UOEwI8Qx5GIkKU1b69o gh9geJTTrDL/voyKhtLHOyDZkY/lBZv1yZ3L59v/31Mj07QVwR5JG1de6sdhL6euxMNZ mCkGmXhMWCIrKmcvAvrO8KM86jF/grdZMI0XEXku6ugvwflpQyyzasUrVsTreDCftIxI l7xQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1794590172; x=1795194972; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=ip7OqnOPWA382+L4zd800WcdSezVmBpGTHBVFqhAjEc=; b=UYXz0qM5ODCA9h8ZdWvvx2Vwp2hMs+S2hsQILQgc5MqgzBD1UFX1hR0au2tUUuPisC fg9LuIOqxnjU9Mt5MNc4XzexP0tVS2QZ1TDS/yuYzDONhjUNcvlRCHqLn/mKGWchqzI9 LdiKAOHej252a84ri77c2ezAztjqaJjYyyevU1jY9CLYTm3oI5B1xJ294eOGatzBebrf pbf+xOJIRO84LHNWRtR8GnrJnPX5BHyksxuNH+avOyV9CohqCvJe10xtmtHyK9PoqUfj wZVoJ9yUkiRZioEHCZKq6rh8dvOyZTAy2/9yZoZtIL1qArjyIsoaSrKrOzIEFApZzg0r aNlg== X-Forwarded-Encrypted: i=1; AL+hErFNm/3+BeCYSbQaIpQdGUHASPZeySCU7iyWeGQ0PhiOpAkB0tZ8XVbtEXw9JqsfyVjDgUAjcTrqXQ0Bk3c=@vger.kernel.org X-Gm-Message-State: APuU4Z/De7eNLvQ1g+m6/tUMkqaRj6fi3/ko+DqlGiHJIS9S0gGw808l 2efPe2gBVcgph3RX4cJ5JSVmluRA9OHcxGSI2GMwsk32xCRLgSz97rXBq21Yt4wMyODYvJEoJ+Z V/HzQh7Jv60+8o4wiBW/edojYUL/+7TA2aqiDsp7tvcnNjwcuBdikC+Zjgtb15NdLpA== X-Gm-Gg: AYBFou3blVw17gyzIinnQ7L1NkHG+0Jb8r0CeERlP2hfDr+b087eRYITSot2DQKVbw3 C1SzMVZBW/5asjNdK/2GpKOKsYS2cQLWx3hIrvvwV1ziXpifnia5wakP/giYjS8NMPelX7fuHHl rITF1eEIi8/3EBONpgEQW7j1fpmAazIxxiC8GXtP54+slu4R6PVluX1j5k0IainFWgRkUmNN+9t t4wGG03w4vAs5zMBKYxGpMc9QZmig3lOpKyqEXSXV8SeCRCgz83bbnI3AcliR3y4bmMKoRczol6 PHRxfnSmlN2qRYGgEU+Cfoq0bZ9osuD6klDBEfTbfoYl+cvCgW2HcA/2v6XVY8u+at5tb/YHHM9 5rY9G6FZCYdT7lJfaQp1qr7O0zDUsRZVEi+NM6Y/CR+ABg5U059hIZs5zIH1drKFbX86jjIjiPS MQrl3sCXj8+Z4= X-Received: by 2002:a05:600c:6d19:b0:4a1:d291:d863 with SMTP id 5b1f17b1804b1-4bb4e2d5f36mr112981295e9.4.1794590169940; Fri, 13 Nov 2026 09:16:09 -0800 (PST) X-Received: by 2002:a05:600c:6d19:b0:4a1:d291:d863 with SMTP id 5b1f17b1804b1-4bb4e2d5f36mr112980595e9.4.1794590169406; Fri, 13 Nov 2026 09:16:09 -0800 (PST) Received: from [192.168.0.19] (217.red-88-4-146.dynamicip.rima-tde.net. [88.4.146.217]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-49c7da37b19sm5811907f8f.5.2026.11.13.09.16.07 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 13 Nov 2026 09:16:08 -0800 (PST) From: Sergio Lopez Date: Fri, 13 Nov 2026 18:15:43 +0100 Subject: [PATCH RFC v3 3/8] vsock/virtio: implement the datagram data path X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit Message-Id: <20261113-vsock-dgram-support-v3-3-1523c8e9b27e@redhat.com> References: <20261113-vsock-dgram-support-v3-0-1523c8e9b27e@redhat.com> In-Reply-To: <20261113-vsock-dgram-support-v3-0-1523c8e9b27e@redhat.com> To: Stefano Garzarella , Bobby Eshleman , Alexei Starovoitov , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Simon Horman , Bryan Tan , Vishnu Dasa , Broadcom internal kernel review list , Stefan Hajnoczi , "Michael S. Tsirkin" , Jason Wang , =?utf-8?q?Eugenio_P=C3=A9rez?= , Xuan Zhuo , Haiyang Zhang , Wei Liu , Dexuan Cui , Shuah Khan , Randy Dunlap Cc: virtualization@lists.linux.dev, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, kvm@vger.kernel.org, bpf@vger.kernel.org, linux-hyperv@vger.kernel.org, Jonathan Corbet , linux-doc@vger.kernel.org, Sergio Lopez X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=11186; i=slp@redhat.com; h=from:subject:message-id; bh=HDuvzaYHkUWJ5X9Jj1YzuMXhUH5TfX/ACn0pbY3JQnw=; b=owEBbQKS/ZANAwAKAfRpJ40vDAI1AcsmYgBq90XJBP0kgtVHSe/hqOKwp58s+JW5sSbTNhFlC Lqaeq32jMmJAjMEAAEKAB0WIQS+1fz3US2GgJFC6KL0aSeNLwwCNQUCavdFyQAKCRD0aSeNLwwC NYaED/9oyx5Q7XVrZjYVGolxu3NLssjvLFlKF3A0xSgN8fn7B5ByrDeTWeDZLlxKuBX+yOP2z6E 5t2VU9SWaV6Vbv+UmMJ1ADgWCjvrL+oloc6ssdy957dJfahaM5P57+f4mtNkBj7DytjZR1Klsnw Y7EByJNCSxWBBGYAcSqeupNAFdr3ffADJAFIwhqpFBbocvGfLgCZEAro0dxlSNBdzPlkvNLhTpK ca9IsCw06BsxakZDhTk0jZV6NYP7Nstmfdaa450cdFFkaC54OPA2tGFOWu91iuNYKhFmeHfJI6G j/djM/pZkQxSC7fdGtHI4Szbz3kmtNfrw41jOkRX0jG5xBzNmZO0krk+w6fKjeH88YHVCrMaS8k UxmDHTa6t+APtSMB+A5xZfETLRQzaE07lgCHzchnkMeK1MdbZ8OX134GZDGTzu77f+HuVgl/bPl 2UnhpSza4MMcuBwP/viL2Wqj+oTtcBJUJbR1Ufz3JqOy8RRfSoCuyAyBxVWk+Vzl3ALqaUZ5pnu 3Zaijv5vH3/a/iU+A8zBS69pE5MZ6rES8dHQfa9v6kHuJ24dAiL3ZVnvVSx0GxluFNa3KM+hfV0 g18o2kWtUv2FW1XEHAI11sYm3bF2xL8G9Kq1UojYVGl7TF9iaec3yikq8tju6hHZ5sSCCUO5M0K rtLoVcf5u05f8IA== X-Developer-Key: i=slp@redhat.com; a=openpgp; fpr=BED5FCF7512D86809142E8A2F469278D2F0C0235 Add the datagram feature bit and packet type, and implement the common virtio transport operations needed to bind, send, and receive datagrams. Send each message as an OP_RW packet with a maximum 64 KiB payload, including support for empty messages. Bound pending sends by the socket send buffer instead of connection-oriented peer credits. Use the socket's skb memory charge for datagram SIOCOUTQ, including empty messages, and release it through the normal skb ownership lifetime on completion, rejection, or queued drops. Deliver incoming datagrams through the datagram bound-socket lookup without entering the connection state machine. Connection-oriented receive lookup excludes datagram sockets, so each class can use the same destination CID and port. Validate the transport and connected peer under the socket lock, including after shutdown, and silently discard undeliverable messages. Use the socket datagram queue for recvmsg(), including source addresses, peeking, and truncation reporting based on the payload length after socket filtering. Reject MSG_OOB and MSG_ERRQUEUE before accessing the receive queue. Reject datagram sockmap admission until its receive callbacks support it. Signed-off-by: Sergio Lopez --- include/uapi/linux/virtio_vsock.h | 2 + net/vmw_vsock/af_vsock.c | 31 +++++--- net/vmw_vsock/virtio_transport_common.c | 132 ++++++++++++++++++++++++++++---- net/vmw_vsock/vsock_bpf.c | 3 +- 4 files changed, 140 insertions(+), 28 deletions(-) diff --git a/include/uapi/linux/virtio_vsock.h b/include/uapi/linux/virtio_vsock.h index 64738838bee5..27b4b2b8bf13 100644 --- a/include/uapi/linux/virtio_vsock.h +++ b/include/uapi/linux/virtio_vsock.h @@ -40,6 +40,7 @@ /* The feature bitmap for virtio vsock */ #define VIRTIO_VSOCK_F_SEQPACKET 1 /* SOCK_SEQPACKET supported */ +#define VIRTIO_VSOCK_F_DGRAM 3 /* SOCK_DGRAM supported */ struct virtio_vsock_config { __le64 guest_cid; @@ -69,6 +70,7 @@ struct virtio_vsock_hdr { enum virtio_vsock_type { VIRTIO_VSOCK_TYPE_STREAM = 1, VIRTIO_VSOCK_TYPE_SEQPACKET = 2, + VIRTIO_VSOCK_TYPE_DGRAM = 3, }; enum virtio_vsock_op { diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c index 8a271eb66860..aef5389eeca2 100644 --- a/net/vmw_vsock/af_vsock.c +++ b/net/vmw_vsock/af_vsock.c @@ -1659,20 +1659,27 @@ static int vsock_do_ioctl(struct socket *sock, unsigned int cmd, case SIOCOUTQ: { ssize_t n_bytes; - if (!vsk->transport || !vsk->transport->unsent_bytes) { - ret = -EOPNOTSUPP; - break; - } + if (sk->sk_type == SOCK_DGRAM) { + /* Match UDP: report charged send memory, including skb + * overhead and empty datagrams. + */ + n_bytes = sk_wmem_alloc_get(sk); + } else { + if (!vsk->transport || !vsk->transport->unsent_bytes) { + ret = -EOPNOTSUPP; + break; + } - if (sock_type_connectible(sk->sk_type) && sk->sk_state == TCP_LISTEN) { - ret = -EINVAL; - break; - } + if (sk->sk_state == TCP_LISTEN) { + ret = -EINVAL; + break; + } - n_bytes = vsk->transport->unsent_bytes(vsk); - if (n_bytes < 0) { - ret = n_bytes; - break; + n_bytes = vsk->transport->unsent_bytes(vsk); + if (n_bytes < 0) { + ret = n_bytes; + break; + } } ret = put_user(n_bytes, arg); diff --git a/net/vmw_vsock/virtio_transport_common.c b/net/vmw_vsock/virtio_transport_common.c index 1e762a480df4..08baa1181ba6 100644 --- a/net/vmw_vsock/virtio_transport_common.c +++ b/net/vmw_vsock/virtio_transport_common.c @@ -204,6 +204,8 @@ static u16 virtio_transport_get_type(struct sock *sk) { if (sk->sk_type == SOCK_STREAM) return VIRTIO_VSOCK_TYPE_STREAM; + else if (sk->sk_type == SOCK_DGRAM) + return VIRTIO_VSOCK_TYPE_DGRAM; else return VIRTIO_VSOCK_TYPE_SEQPACKET; } @@ -303,6 +305,7 @@ static int virtio_transport_send_pkt_info(struct vsock_sock *vsk, u32 src_cid, src_port, dst_cid, dst_port; const struct virtio_transport *t_ops; struct iov_iter_state msg_iter_state; + struct sock *sk = sk_vsock(vsk); struct virtio_vsock_sock *vvs; struct ubuf_info *uarg = NULL; u32 pkt_len = info->pkt_len; @@ -327,14 +330,27 @@ static int virtio_transport_send_pkt_info(struct vsock_sock *vsk, dst_port = info->remote_port; } - vvs = vsk->trans; + /* Datagram sends use socket memory accounting instead of peer credits. */ + vvs = info->type == VIRTIO_VSOCK_TYPE_DGRAM ? NULL : vsk->trans; - /* virtio_transport_get_credit might return less than pkt_len credit */ - pkt_len = virtio_transport_get_credit(vvs, pkt_len); + if (info->type == VIRTIO_VSOCK_TYPE_DGRAM) { + if (pkt_len > VIRTIO_VSOCK_MAX_PKT_BUF_SIZE) + return -EMSGSIZE; - /* Do not send zero length OP_RW pkt */ - if (pkt_len == 0 && info->op == VIRTIO_VSOCK_OP_RW) - return pkt_len; + /* Datagram sends are serialized by the socket lock. */ + if (sk_wmem_alloc_get(sk) >= READ_ONCE(sk->sk_sndbuf)) { + sk_set_bit(SOCKWQ_ASYNC_NOSPACE, sk); + set_bit(SOCK_NOSPACE, &sk->sk_socket->flags); + return -EAGAIN; + } + } else { + /* virtio_transport_get_credit might return less than pkt_len credit */ + pkt_len = virtio_transport_get_credit(vvs, pkt_len); + + /* Do not send zero length OP_RW pkt */ + if (pkt_len == 0 && info->op == VIRTIO_VSOCK_OP_RW) + return pkt_len; + } if (info->msg && (info->msg->msg_flags & MSG_ZEROCOPY)) { /* If 'info->msg' is not NULL, this is only VIRTIO_VSOCK_OP_RW. @@ -348,7 +364,8 @@ static int virtio_transport_send_pkt_info(struct vsock_sock *vsk, uarg = msg_zerocopy_realloc(sk_vsock(vsk), pkt_len, NULL, false); if (!uarg) { - virtio_transport_put_credit(vvs, pkt_len); + if (info->type != VIRTIO_VSOCK_TYPE_DGRAM) + virtio_transport_put_credit(vvs, pkt_len); return -ENOMEM; } @@ -393,7 +410,8 @@ static int virtio_transport_send_pkt_info(struct vsock_sock *vsk, break; } - virtio_transport_inc_tx_pkt(vvs, skb); + if (info->type != VIRTIO_VSOCK_TYPE_DGRAM) + virtio_transport_inc_tx_pkt(vvs, skb); ret = t_ops->send_pkt(skb, info->net); if (ret < 0) @@ -416,7 +434,8 @@ static int virtio_transport_send_pkt_info(struct vsock_sock *vsk, if (info->msg && ret < 0) iov_iter_restore(&info->msg->msg_iter, &msg_iter_state); - virtio_transport_put_credit(vvs, rest_len); + if (info->type != VIRTIO_VSOCK_TYPE_DGRAM) + virtio_transport_put_credit(vvs, rest_len); /* msg_zerocopy_realloc() initializes the ubuf_info refcnt to 1. * skb_zcopy_set() increases it for each skb, so we can drop that @@ -620,7 +639,7 @@ void virtio_transport_consume_skb_sent(struct sk_buff *skb, bool consume) { struct sock *s = skb->sk; - if (s && skb->len) { + if (s && skb->len && s->sk_type != SOCK_DGRAM) { struct vsock_sock *vs = vsock_sk(s); struct virtio_vsock_sock *vvs; @@ -999,7 +1018,47 @@ virtio_transport_dgram_dequeue(struct vsock_sock *vsk, struct msghdr *msg, size_t len, int flags) { - return -EOPNOTSUPP; + struct sock *sk = sk_vsock(vsk); + struct virtio_vsock_hdr *hdr; + struct sk_buff *skb; + size_t payload_len; + int err; + + if (flags & (MSG_OOB | MSG_ERRQUEUE)) + return -EOPNOTSUPP; + + skb = skb_recv_datagram(sk, flags, &err); + if (!skb) + return err; + + hdr = virtio_vsock_hdr(skb); + payload_len = skb->len; + + if (payload_len > len) { + payload_len = len; + msg->msg_flags |= MSG_TRUNC; + } + + err = skb_copy_datagram_iter(skb, 0, &msg->msg_iter, payload_len); + if (err) + goto out; + + if (msg->msg_name) { + DECLARE_SOCKADDR(struct sockaddr_vm *, vm_addr, msg->msg_name); + + vsock_addr_init(vm_addr, le64_to_cpu(hdr->src_cid), + le32_to_cpu(hdr->src_port)); + msg->msg_namelen = sizeof(*vm_addr); + } + + if (flags & MSG_TRUNC) + err = skb->len; + else + err = payload_len; + +out: + skb_free_datagram(sk, skb); + return err; } EXPORT_SYMBOL_GPL(virtio_transport_dgram_dequeue); @@ -1202,13 +1261,13 @@ EXPORT_SYMBOL_GPL(virtio_transport_stream_is_active); int virtio_transport_dgram_bind(struct vsock_sock *vsk, struct sockaddr_vm *addr) { - return -EOPNOTSUPP; + return vsock_bind_common(vsk, addr); } EXPORT_SYMBOL_GPL(virtio_transport_dgram_bind); bool virtio_transport_dgram_allow(struct vsock_sock *vsk, u32 cid, u32 port) { - return false; + return true; } EXPORT_SYMBOL_GPL(virtio_transport_dgram_allow); @@ -1246,7 +1305,17 @@ virtio_transport_dgram_enqueue(struct vsock_sock *vsk, struct msghdr *msg, size_t dgram_len) { - return -EOPNOTSUPP; + struct virtio_vsock_pkt_info info = { + .op = VIRTIO_VSOCK_OP_RW, + .msg = msg, + .pkt_len = dgram_len, + .vsk = vsk, + .remote_cid = remote_addr->svm_cid, + .remote_port = remote_addr->svm_port, + .net = sock_net(sk_vsock(vsk)), + }; + + return virtio_transport_send_pkt_info(vsk, &info); } EXPORT_SYMBOL_GPL(virtio_transport_dgram_enqueue); @@ -1771,7 +1840,8 @@ virtio_transport_recv_listen(struct sock *sk, struct sk_buff *skb, static bool virtio_transport_valid_type(u16 type) { return (type == VIRTIO_VSOCK_TYPE_STREAM) || - (type == VIRTIO_VSOCK_TYPE_SEQPACKET); + (type == VIRTIO_VSOCK_TYPE_SEQPACKET) || + (type == VIRTIO_VSOCK_TYPE_DGRAM); } /* We are under the virtio-vsock's vsock->rx_lock or vhost-vsock's vq->mutex @@ -1805,6 +1875,38 @@ void virtio_transport_recv_pkt(struct virtio_transport *t, goto free_pkt; } + /* Dgram packets are delivered directly to bound sockets without + * going through the connection state machine. Undeliverable + * datagrams are silently dropped (no RST). + */ + if (le16_to_cpu(hdr->type) == VIRTIO_VSOCK_TYPE_DGRAM) { + if (le16_to_cpu(hdr->op) != VIRTIO_VSOCK_OP_RW) + goto free_pkt; + + sk = vsock_find_bound_dgram_socket_net(&dst, net); + + if (!sk) + goto free_pkt; + + vsk = vsock_sk(sk); + lock_sock(sk); + if (sock_flag(sk, SOCK_DEAD) || + vsk->transport != &t->transport || + (sk->sk_socket->state != SS_UNCONNECTED && + !vsock_check_source(vsk, &t->transport, &src))) { + release_sock(sk); + sock_put(sk); + goto free_pkt; + } + + if (sock_queue_rcv_skb(sk, skb)) + kfree_skb(skb); + + release_sock(sk); + sock_put(sk); + return; + } + /* The socket must be in connected or bound table * otherwise send reset back */ diff --git a/net/vmw_vsock/vsock_bpf.c b/net/vmw_vsock/vsock_bpf.c index 9049d2648646..296e1fa7970b 100644 --- a/net/vmw_vsock/vsock_bpf.c +++ b/net/vmw_vsock/vsock_bpf.c @@ -161,7 +161,8 @@ int vsock_bpf_update_proto(struct sock *sk, struct sk_psock *psock, bool restore if (!vsk->transport) return -ENODEV; - if (!vsk->transport->read_skb) + /* Datagram receive is not implemented by the sockmap callbacks. */ + if (sk->sk_type == SOCK_DGRAM || !vsk->transport->read_skb) return -EOPNOTSUPP; vsock_bpf_check_needs_rebuild(psock->sk_proto); -- 2.56.0