|
@@ -719,6 +719,7 @@ static ssize_t macvtap_get_user(struct macvtap_queue *q, struct msghdr *m,
|
|
|
struct virtio_net_hdr vnet_hdr = { 0 };
|
|
|
int vnet_hdr_len = 0;
|
|
|
int copylen = 0;
|
|
|
+ int depth;
|
|
|
bool zerocopy = false;
|
|
|
size_t linear;
|
|
|
ssize_t n;
|
|
@@ -804,6 +805,12 @@ static ssize_t macvtap_get_user(struct macvtap_queue *q, struct msghdr *m,
|
|
|
|
|
|
skb_probe_transport_header(skb, ETH_HLEN);
|
|
|
|
|
|
+ /* Move network header to the right position for VLAN tagged packets */
|
|
|
+ if ((skb->protocol == htons(ETH_P_8021Q) ||
|
|
|
+ skb->protocol == htons(ETH_P_8021AD)) &&
|
|
|
+ __vlan_get_protocol(skb, skb->protocol, &depth) != 0)
|
|
|
+ skb_set_network_header(skb, depth);
|
|
|
+
|
|
|
rcu_read_lock();
|
|
|
vlan = rcu_dereference(q->vlan);
|
|
|
/* copy skb_ubuf_info for callback when skb has no error */
|