mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-11 21:38:32 +08:00
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>
This commit is contained in:
parent
64c99d2d6a
commit
4b0bf10eb0
@ -106,6 +106,27 @@ out:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
@ -114,7 +135,6 @@ static struct sk_buff *virtio_transport_build_skb(void *opaque)
|
||||
struct af_vsockmon_hdr *hdr;
|
||||
struct sk_buff *skb;
|
||||
size_t payload_len;
|
||||
void *payload_buf;
|
||||
|
||||
/* 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
|
||||
@ -122,7 +142,6 @@ static struct sk_buff *virtio_transport_build_skb(void *opaque)
|
||||
*/
|
||||
pkt_hdr = virtio_vsock_hdr(pkt);
|
||||
payload_len = pkt->len;
|
||||
payload_buf = pkt->data;
|
||||
|
||||
skb = alloc_skb(sizeof(*hdr) + sizeof(*pkt_hdr) + payload_len,
|
||||
GFP_ATOMIC);
|
||||
@ -165,7 +184,13 @@ static struct sk_buff *virtio_transport_build_skb(void *opaque)
|
||||
skb_put_data(skb, pkt_hdr, sizeof(*pkt_hdr));
|
||||
|
||||
if (payload_len) {
|
||||
skb_put_data(skb, payload_buf, payload_len);
|
||||
if (skb_is_nonlinear(pkt)) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
return skb;
|
||||
|
Loading…
Reference in New Issue
Block a user