diff options
| -rw-r--r-- | include/linux/if_vlan.h | 15 |
1 files changed, 13 insertions, 2 deletions
diff --git a/include/linux/if_vlan.h b/include/linux/if_vlan.h index c4a1cff9c768..7d30892da064 100644 --- a/include/linux/if_vlan.h +++ b/include/linux/if_vlan.h | |||
| @@ -323,13 +323,24 @@ static inline int __vlan_insert_inner_tag(struct sk_buff *skb, | |||
| 323 | skb_push(skb, VLAN_HLEN); | 323 | skb_push(skb, VLAN_HLEN); |
| 324 | 324 | ||
| 325 | /* Move the mac header sans proto to the beginning of the new header. */ | 325 | /* Move the mac header sans proto to the beginning of the new header. */ |
| 326 | memmove(skb->data, skb->data + VLAN_HLEN, mac_len - ETH_TLEN); | 326 | if (likely(mac_len > ETH_TLEN)) |
| 327 | memmove(skb->data, skb->data + VLAN_HLEN, mac_len - ETH_TLEN); | ||
| 327 | skb->mac_header -= VLAN_HLEN; | 328 | skb->mac_header -= VLAN_HLEN; |
| 328 | 329 | ||
| 329 | veth = (struct vlan_ethhdr *)(skb->data + mac_len - ETH_HLEN); | 330 | veth = (struct vlan_ethhdr *)(skb->data + mac_len - ETH_HLEN); |
| 330 | 331 | ||
| 331 | /* first, the ethernet type */ | 332 | /* first, the ethernet type */ |
| 332 | veth->h_vlan_proto = vlan_proto; | 333 | if (likely(mac_len >= ETH_TLEN)) { |
| 334 | /* h_vlan_encapsulated_proto should already be populated, and | ||
| 335 | * skb->data has space for h_vlan_proto | ||
| 336 | */ | ||
| 337 | veth->h_vlan_proto = vlan_proto; | ||
| 338 | } else { | ||
| 339 | /* h_vlan_encapsulated_proto should not be populated, and | ||
| 340 | * skb->data has no space for h_vlan_proto | ||
| 341 | */ | ||
| 342 | veth->h_vlan_encapsulated_proto = skb->protocol; | ||
| 343 | } | ||
| 333 | 344 | ||
| 334 | /* now, the TCI */ | 345 | /* now, the TCI */ |
| 335 | veth->h_vlan_TCI = htons(vlan_tci); | 346 | veth->h_vlan_TCI = htons(vlan_tci); |
