union {
                void *ptr;
                struct ethhdr *eth;
+               struct vlan_ethhdr *veth;
                struct iphdr *ipv4;
                struct ipv6hdr *ipv6;
                struct tcphdr *tcp;
        if (unlikely(sizeof(struct iphdr) + sizeof(struct tcphdr) > maplen))
                return 0;
 
+       if (skb->protocol == cpu_to_be16(ETH_P_8021Q) ||
+           skb->protocol == cpu_to_be16(ETH_P_8021AD))
+               hlen = sizeof(struct vlan_ethhdr);
+       else
+               hlen = sizeof(struct ethhdr);
+
        hdr.eth = eth_hdr(skb);
        if (gdesc->rcd.v4) {
-               BUG_ON(hdr.eth->h_proto != htons(ETH_P_IP));
-               hdr.ptr += sizeof(struct ethhdr);
+               BUG_ON(hdr.eth->h_proto != htons(ETH_P_IP) &&
+                      hdr.veth->h_vlan_encapsulated_proto != htons(ETH_P_IP));
+               hdr.ptr += hlen;
                BUG_ON(hdr.ipv4->protocol != IPPROTO_TCP);
                hlen = hdr.ipv4->ihl << 2;
                hdr.ptr += hdr.ipv4->ihl << 2;
        } else if (gdesc->rcd.v6) {
-               BUG_ON(hdr.eth->h_proto != htons(ETH_P_IPV6));
-               hdr.ptr += sizeof(struct ethhdr);
+               BUG_ON(hdr.eth->h_proto != htons(ETH_P_IPV6) &&
+                      hdr.veth->h_vlan_encapsulated_proto != htons(ETH_P_IPV6));
+               hdr.ptr += hlen;
                /* Use an estimated value, since we also need to handle
                 * TSO case.
                 */
 
 /*
  * Version numbers
  */
-#define VMXNET3_DRIVER_VERSION_STRING   "1.4.13.0-k"
+#define VMXNET3_DRIVER_VERSION_STRING   "1.4.14.0-k"
 
 /* a 32-bit int, each byte encode a verion number in VMXNET3_DRIVER_VERSION */
-#define VMXNET3_DRIVER_VERSION_NUM      0x01040d00
+#define VMXNET3_DRIVER_VERSION_NUM      0x01040e00
 
 #if defined(CONFIG_PCI_MSI)
        /* RSS only makes sense if MSI-X is supported. */