summaryrefslogtreecommitdiff
path: root/drivers/net/macvtap.c
diff options
context:
space:
mode:
authorChris Zankel <chris@zankel.net>2015-08-29 23:55:58 (GMT)
committerChris Zankel <chris@zankel.net>2015-08-29 23:55:58 (GMT)
commit650c919798c71fb34b77a6f2ba03a06907f06a76 (patch)
treed1c60012d4d86846d25f1d0b783b5122c26a2e31 /drivers/net/macvtap.c
parent895fb3159280fe7695b35ec7c87ec19e13ca5b6e (diff)
parent64291f7db5bd8150a74ad2036f1037e6a0428df2 (diff)
downloadlinux-650c919798c71fb34b77a6f2ba03a06907f06a76.tar.xz
Merge tag 'v4.2' into for_next
Linux 4.2
Diffstat (limited to 'drivers/net/macvtap.c')
-rw-r--r--drivers/net/macvtap.c8
1 files changed, 8 insertions, 0 deletions
diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c
index f837080..edd7734 100644
--- a/drivers/net/macvtap.c
+++ b/drivers/net/macvtap.c
@@ -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 */
@@ -1355,6 +1362,7 @@ static void macvtap_exit(void)
class_unregister(macvtap_class);
cdev_del(&macvtap_cdev);
unregister_chrdev_region(macvtap_major, MACVTAP_NUM_DEVS);
+ idr_destroy(&minor_idr);
}
module_exit(macvtap_exit);