|
@@ -1042,7 +1042,7 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile,
|
|
|
{
|
|
|
struct tun_pi pi = { 0, cpu_to_be16(ETH_P_IP) };
|
|
|
struct sk_buff *skb;
|
|
|
- size_t len = total_len, align = NET_SKB_PAD;
|
|
|
+ size_t len = total_len, align = NET_SKB_PAD, linear;
|
|
|
struct virtio_net_hdr gso = { 0 };
|
|
|
int offset = 0;
|
|
|
int copylen;
|
|
@@ -1106,10 +1106,13 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile,
|
|
|
copylen = gso.hdr_len;
|
|
|
if (!copylen)
|
|
|
copylen = GOODCOPY_LEN;
|
|
|
- } else
|
|
|
+ linear = copylen;
|
|
|
+ } else {
|
|
|
copylen = len;
|
|
|
+ linear = gso.hdr_len;
|
|
|
+ }
|
|
|
|
|
|
- skb = tun_alloc_skb(tfile, align, copylen, gso.hdr_len, noblock);
|
|
|
+ skb = tun_alloc_skb(tfile, align, copylen, linear, noblock);
|
|
|
if (IS_ERR(skb)) {
|
|
|
if (PTR_ERR(skb) != -EAGAIN)
|
|
|
tun->dev->stats.rx_dropped++;
|