diff options
-rw-r--r-- | net/core/dev.c | 12 |
1 files changed, 7 insertions, 5 deletions
diff --git a/net/core/dev.c b/net/core/dev.c index 0b403d503311..368930a988e3 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -1794,16 +1794,18 @@ struct sk_buff *skb_gso_segment(struct sk_buff *skb, int features) | |||
1794 | struct sk_buff *segs = ERR_PTR(-EPROTONOSUPPORT); | 1794 | struct sk_buff *segs = ERR_PTR(-EPROTONOSUPPORT); |
1795 | struct packet_type *ptype; | 1795 | struct packet_type *ptype; |
1796 | __be16 type = skb->protocol; | 1796 | __be16 type = skb->protocol; |
1797 | int vlan_depth = ETH_HLEN; | ||
1797 | int err; | 1798 | int err; |
1798 | 1799 | ||
1799 | if (type == htons(ETH_P_8021Q)) { | 1800 | while (type == htons(ETH_P_8021Q)) { |
1800 | struct vlan_ethhdr *veh; | 1801 | struct vlan_hdr *vh; |
1801 | 1802 | ||
1802 | if (unlikely(!pskb_may_pull(skb, VLAN_ETH_HLEN))) | 1803 | if (unlikely(!pskb_may_pull(skb, vlan_depth + VLAN_HLEN))) |
1803 | return ERR_PTR(-EINVAL); | 1804 | return ERR_PTR(-EINVAL); |
1804 | 1805 | ||
1805 | veh = (struct vlan_ethhdr *)skb->data; | 1806 | vh = (struct vlan_hdr *)(skb->data + vlan_depth); |
1806 | type = veh->h_vlan_encapsulated_proto; | 1807 | type = vh->h_vlan_encapsulated_proto; |
1808 | vlan_depth += VLAN_HLEN; | ||
1807 | } | 1809 | } |
1808 | 1810 | ||
1809 | skb_reset_mac_header(skb); | 1811 | skb_reset_mac_header(skb); |