mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-16 02:01:18 -04:00
Merge branch 'vsock-virtio-fix-vsockmon-tap-skb-construction'
Stefano Garzarella says: ==================== vsock/virtio: fix vsockmon tap skb construction While reviewing the patch posted by Yiqi Sun [1] to fix an issue in virtio_transport_build_skb(), I discovered another issue related to the offset and length of the payload to be copied in the new skb. This was introduced when we did the skb conversion, and fixed by patch 1. Patch 2 fixes the issue found by Yiqi Sun in a different way: using iov_iter_kvec() to properly initialize all the iov_iter fields and removing the linear vs non-linear split like we alredy do in vhost-vsock. It could have been a single patch, but since there were two affected commits, I decided to keep the fixes separate. [1] https://lore.kernel.org/netdev/20260430071110.380509-1-sunyiqixm@gmail.com/ ==================== Link: https://patch.msgid.link/20260508164411.261440-1-sgarzare@redhat.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
This commit is contained in:
@@ -136,27 +136,6 @@ static void virtio_transport_init_hdr(struct sk_buff *skb,
|
||||
hdr->fwd_cnt = cpu_to_le32(0);
|
||||
}
|
||||
|
||||
static void virtio_transport_copy_nonlinear_skb(const struct sk_buff *skb,
|
||||
void *dst,
|
||||
size_t len)
|
||||
{
|
||||
struct iov_iter iov_iter = { 0 };
|
||||
struct kvec kvec;
|
||||
size_t to_copy;
|
||||
|
||||
kvec.iov_base = dst;
|
||||
kvec.iov_len = len;
|
||||
|
||||
iov_iter.iter_type = ITER_KVEC;
|
||||
iov_iter.kvec = &kvec;
|
||||
iov_iter.nr_segs = 1;
|
||||
|
||||
to_copy = min_t(size_t, len, skb->len);
|
||||
|
||||
skb_copy_datagram_iter(skb, VIRTIO_VSOCK_SKB_CB(skb)->offset,
|
||||
&iov_iter, to_copy);
|
||||
}
|
||||
|
||||
/* Packet capture */
|
||||
static struct sk_buff *virtio_transport_build_skb(void *opaque)
|
||||
{
|
||||
@@ -166,12 +145,12 @@ static struct sk_buff *virtio_transport_build_skb(void *opaque)
|
||||
struct sk_buff *skb;
|
||||
size_t payload_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.
|
||||
/* A packet could be split to fit the RX buffer, so we use
|
||||
* the payload length from the header, which has been updated
|
||||
* by the sender to reflect the fragment size.
|
||||
*/
|
||||
pkt_hdr = virtio_vsock_hdr(pkt);
|
||||
payload_len = pkt->len;
|
||||
payload_len = le32_to_cpu(pkt_hdr->len);
|
||||
|
||||
skb = alloc_skb(sizeof(*hdr) + sizeof(*pkt_hdr) + payload_len,
|
||||
GFP_ATOMIC);
|
||||
@@ -214,12 +193,18 @@ static struct sk_buff *virtio_transport_build_skb(void *opaque)
|
||||
skb_put_data(skb, pkt_hdr, sizeof(*pkt_hdr));
|
||||
|
||||
if (payload_len) {
|
||||
if (skb_is_nonlinear(pkt)) {
|
||||
void *data = skb_put(skb, payload_len);
|
||||
struct iov_iter iov_iter;
|
||||
struct kvec kvec;
|
||||
void *data = skb_put(skb, payload_len);
|
||||
|
||||
virtio_transport_copy_nonlinear_skb(pkt, data, payload_len);
|
||||
} else {
|
||||
skb_put_data(skb, pkt->data, payload_len);
|
||||
kvec.iov_base = data;
|
||||
kvec.iov_len = payload_len;
|
||||
iov_iter_kvec(&iov_iter, ITER_DEST, &kvec, 1, payload_len);
|
||||
|
||||
if (skb_copy_datagram_iter(pkt, VIRTIO_VSOCK_SKB_CB(pkt)->offset,
|
||||
&iov_iter, payload_len)) {
|
||||
kfree_skb(skb);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user