| From: Toshiaki Makita <makita.toshiaki@lab.ntt.co.jp> |
| Date: Mon, 22 Dec 2014 19:04:14 +0900 |
| Subject: net: Fix stacked vlan offload features computation |
| |
| commit 796f2da81bead71ffc91ef70912cd8d1827bf756 upstream. |
| |
| When vlan tags are stacked, it is very likely that the outer tag is stored |
| in skb->vlan_tci and skb->protocol shows the inner tag's vlan_proto. |
| Currently netif_skb_features() first looks at skb->protocol even if there |
| is the outer tag in vlan_tci, thus it incorrectly retrieves the protocol |
| encapsulated by the inner vlan instead of the inner vlan protocol. |
| This allows GSO packets to be passed to HW and they end up being |
| corrupted. |
| |
| Fixes: 58e998c6d239 ("offloading: Force software GSO for multiple vlan tags.") |
| Signed-off-by: Toshiaki Makita <makita.toshiaki@lab.ntt.co.jp> |
| Signed-off-by: David S. Miller <davem@davemloft.net> |
| [bwh: Backported to 3.2: |
| - We don't support 802.1ad tag offload |
| - Keep passing protocol to harmonize_features()] |
| Signed-off-by: Ben Hutchings <ben@decadent.org.uk> |
| --- |
| --- a/net/core/dev.c |
| +++ b/net/core/dev.c |
| @@ -2128,11 +2128,13 @@ u32 netif_skb_features(struct sk_buff *s |
| if (skb_shinfo(skb)->gso_segs > skb->dev->gso_max_segs) |
| features &= ~NETIF_F_GSO_MASK; |
| |
| - if (protocol == htons(ETH_P_8021Q)) { |
| - struct vlan_ethhdr *veh = (struct vlan_ethhdr *)skb->data; |
| - protocol = veh->h_vlan_encapsulated_proto; |
| - } else if (!vlan_tx_tag_present(skb)) { |
| - return harmonize_features(skb, protocol, features); |
| + if (!vlan_tx_tag_present(skb)) { |
| + if (unlikely(protocol == htons(ETH_P_8021Q))) { |
| + struct vlan_ethhdr *veh = (struct vlan_ethhdr *)skb->data; |
| + protocol = veh->h_vlan_encapsulated_proto; |
| + } else { |
| + return harmonize_features(skb, protocol, features); |
| + } |
| } |
| |
| features &= (skb->dev->vlan_features | NETIF_F_HW_VLAN_TX); |