{
        struct tun_pi pi = { 0, skb->protocol };
        ssize_t total = 0;
-       int vlan_offset = 0;
+       int vlan_offset = 0, copied;
 
        if (!(tun->flags & TUN_NO_PI)) {
                if ((len -= sizeof(pi)) < 0)
                total += tun->vnet_hdr_sz;
        }
 
+       copied = total;
+       total += skb->len;
        if (!vlan_tx_tag_present(skb)) {
                len = min_t(int, skb->len, len);
        } else {
 
                vlan_offset = offsetof(struct vlan_ethhdr, h_vlan_proto);
                len = min_t(int, skb->len + VLAN_HLEN, len);
+               total += VLAN_HLEN;
 
                copy = min_t(int, vlan_offset, len);
-               ret = skb_copy_datagram_const_iovec(skb, 0, iv, total, copy);
+               ret = skb_copy_datagram_const_iovec(skb, 0, iv, copied, copy);
                len -= copy;
-               total += copy;
+               copied += copy;
                if (ret || !len)
                        goto done;
 
                copy = min_t(int, sizeof(veth), len);
-               ret = memcpy_toiovecend(iv, (void *)&veth, total, copy);
+               ret = memcpy_toiovecend(iv, (void *)&veth, copied, copy);
                len -= copy;
-               total += copy;
+               copied += copy;
                if (ret || !len)
                        goto done;
        }
 
-       skb_copy_datagram_const_iovec(skb, vlan_offset, iv, total, len);
-       total += len;
+       skb_copy_datagram_const_iovec(skb, vlan_offset, iv, copied, len);
 
 done:
        tun->dev->stats.tx_packets++;