Skip to content

Commit 4b0bf10

Browse files
Arseniy KrasnovPaolo Abeni
authored andcommitted
vsock/virtio: non-linear skb handling for tap
For tap device new skb is created and data from the current skb is copied to it. This adds copying data from non-linear skb to new the skb. Signed-off-by: Arseniy Krasnov <avkrasnov@salutedevices.com> Reviewed-by: Stefano Garzarella <sgarzare@redhat.com> Acked-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Paolo Abeni <pabeni@redhat.com>
1 parent 64c99d2 commit 4b0bf10

1 file changed

Lines changed: 28 additions & 3 deletions

File tree

net/vmw_vsock/virtio_transport_common.c

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,27 @@ virtio_transport_alloc_skb(struct virtio_vsock_pkt_info *info,
106106
return NULL;
107107
}
108108

109+
static void virtio_transport_copy_nonlinear_skb(const struct sk_buff *skb,
110+
void *dst,
111+
size_t len)
112+
{
113+
struct iov_iter iov_iter = { 0 };
114+
struct kvec kvec;
115+
size_t to_copy;
116+
117+
kvec.iov_base = dst;
118+
kvec.iov_len = len;
119+
120+
iov_iter.iter_type = ITER_KVEC;
121+
iov_iter.kvec = &kvec;
122+
iov_iter.nr_segs = 1;
123+
124+
to_copy = min_t(size_t, len, skb->len);
125+
126+
skb_copy_datagram_iter(skb, VIRTIO_VSOCK_SKB_CB(skb)->offset,
127+
&iov_iter, to_copy);
128+
}
129+
109130
/* Packet capture */
110131
static struct sk_buff *virtio_transport_build_skb(void *opaque)
111132
{
@@ -114,15 +135,13 @@ static struct sk_buff *virtio_transport_build_skb(void *opaque)
114135
struct af_vsockmon_hdr *hdr;
115136
struct sk_buff *skb;
116137
size_t payload_len;
117-
void *payload_buf;
118138

119139
/* A packet could be split to fit the RX buffer, so we can retrieve
120140
* the payload length from the header and the buffer pointer taking
121141
* care of the offset in the original packet.
122142
*/
123143
pkt_hdr = virtio_vsock_hdr(pkt);
124144
payload_len = pkt->len;
125-
payload_buf = pkt->data;
126145

127146
skb = alloc_skb(sizeof(*hdr) + sizeof(*pkt_hdr) + payload_len,
128147
GFP_ATOMIC);
@@ -165,7 +184,13 @@ static struct sk_buff *virtio_transport_build_skb(void *opaque)
165184
skb_put_data(skb, pkt_hdr, sizeof(*pkt_hdr));
166185

167186
if (payload_len) {
168-
skb_put_data(skb, payload_buf, payload_len);
187+
if (skb_is_nonlinear(pkt)) {
188+
void *data = skb_put(skb, payload_len);
189+
190+
virtio_transport_copy_nonlinear_skb(pkt, data, payload_len);
191+
} else {
192+
skb_put_data(skb, pkt->data, payload_len);
193+
}
169194
}
170195

171196
return skb;

0 commit comments

Comments
 (0)