#include <linux/virtio_net.h>
 #include <linux/errqueue.h>
 #include <linux/net_tstamp.h>
+#include <linux/if_arp.h>
 
 #ifdef CONFIG_INET
 #include <net/inet_common.h>
                if (unlikely(err))
                        return err;
 
+               if (dev->type == ARPHRD_ETHER)
+                       skb->protocol = eth_type_trans(skb, dev);
+
                data += dev->hard_header_len;
                to_write -= dev->hard_header_len;
        }
 
        sock_tx_timestamp(sk, &skb_shinfo(skb)->tx_flags);
 
+       if (dev->type == ARPHRD_ETHER) {
+               skb->protocol = eth_type_trans(skb, dev);
+       } else {
+               skb->protocol = proto;
+               skb->dev = dev;
+       }
+
        if (!gso_type && (len > dev->mtu + reserve + extra_len)) {
                /* Earlier code assumed this would be a VLAN pkt,
                 * double-check this now that we have the actual
                }
        }
 
-       skb->protocol = proto;
-       skb->dev = dev;
        skb->priority = sk->sk_priority;
        skb->mark = sk->sk_mark;