summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorStefano Garzarella <sgarzare@redhat.com>2019-07-30 17:43:33 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2019-12-01 09:16:08 +0100
commit70d594d17ebb5c4e98bba6da2ec665fdbf82b0cb (patch)
tree33cd01b358340ebba2c96ee180f8beb5078a4c37 /net
parent48bc34efbc655e9f569c1620d13fc7d3182d6f2d (diff)
downloadlinux-stable-70d594d17ebb5c4e98bba6da2ec665fdbf82b0cb.tar.gz
linux-stable-70d594d17ebb5c4e98bba6da2ec665fdbf82b0cb.tar.bz2
linux-stable-70d594d17ebb5c4e98bba6da2ec665fdbf82b0cb.zip
vhost/vsock: split packets to send using multiple buffers
commit 6dbd3e66e7785a2f055bf84d98de9b8fd31ff3f5 upstream. If the packets to sent to the guest are bigger than the buffer available, we can split them, using multiple buffers and fixing the length in the packet header. This is safe since virtio-vsock supports only stream sockets. Signed-off-by: Stefano Garzarella <sgarzare@redhat.com> Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> Acked-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'net')
-rw-r--r--net/vmw_vsock/virtio_transport_common.c15
1 files changed, 12 insertions, 3 deletions
diff --git a/net/vmw_vsock/virtio_transport_common.c b/net/vmw_vsock/virtio_transport_common.c
index 2a8651aa90c8..52242a148c70 100644
--- a/net/vmw_vsock/virtio_transport_common.c
+++ b/net/vmw_vsock/virtio_transport_common.c
@@ -92,8 +92,17 @@ static struct sk_buff *virtio_transport_build_skb(void *opaque)
struct virtio_vsock_pkt *pkt = opaque;
struct af_vsockmon_hdr *hdr;
struct sk_buff *skb;
+ size_t payload_len;
+ void *payload_buf;
- skb = alloc_skb(sizeof(*hdr) + sizeof(pkt->hdr) + pkt->len,
+ /* A packet could be split to fit the RX buffer, so we can retrieve
+ * the payload length from the header and the buffer pointer taking
+ * care of the offset in the original packet.
+ */
+ payload_len = le32_to_cpu(pkt->hdr.len);
+ payload_buf = pkt->buf + pkt->off;
+
+ skb = alloc_skb(sizeof(*hdr) + sizeof(pkt->hdr) + payload_len,
GFP_ATOMIC);
if (!skb)
return NULL;
@@ -133,8 +142,8 @@ static struct sk_buff *virtio_transport_build_skb(void *opaque)
skb_put_data(skb, &pkt->hdr, sizeof(pkt->hdr));
- if (pkt->len) {
- skb_put_data(skb, pkt->buf, pkt->len);
+ if (payload_len) {
+ skb_put_data(skb, payload_buf, payload_len);
}
return skb;