diff options
author | Cong Wang <amwang@redhat.com> | 2013-02-21 18:32:27 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-02-23 21:00:06 -0500 |
commit | da8c87241c26aac81a64c7e4d21d438a33018f4e (patch) | |
tree | ff2224eaeac133a20ce0ab7f128d386a8216c4b3 /include/linux/if_vlan.h | |
parent | 8e904550d0fffcda2b18d7ab12750b0c75757e89 (diff) |
vlan: adjust vlan_set_encap_proto() for its callers
There are two places to call vlan_set_encap_proto():
vlan_untag() and __pop_vlan_tci().
vlan_untag() assumes skb->data points after mac addr, otherwise
the following code
vhdr = (struct vlan_hdr *) skb->data;
vlan_tci = ntohs(vhdr->h_vlan_TCI);
__vlan_hwaccel_put_tag(skb, vlan_tci);
skb_pull_rcsum(skb, VLAN_HLEN);
won't be correct. But __pop_vlan_tci() assumes points _before_
mac addr.
In vlan_set_encap_proto(), it looks for some magic L2 value
after mac addr:
rawp = skb->data;
if (*(unsigned short *) rawp == 0xFFFF)
...
Therefore __pop_vlan_tci() is obviously wrong.
A quick fix is avoiding using skb->data in vlan_set_encap_proto(),
use 'vhdr+1' is always correct in both cases.
Cc: David S. Miller <davem@davemloft.net>
Cc: Jesse Gross <jesse@nicira.com>
Signed-off-by: Cong Wang <amwang@redhat.com>
Acked-by: Jesse Gross <jesse@nicira.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include/linux/if_vlan.h')
-rw-r--r-- | include/linux/if_vlan.h | 6 |
1 files changed, 3 insertions, 3 deletions
diff --git a/include/linux/if_vlan.h b/include/linux/if_vlan.h index d06cc5c8f58c..218a3b686d90 100644 --- a/include/linux/if_vlan.h +++ b/include/linux/if_vlan.h | |||
@@ -331,7 +331,7 @@ static inline void vlan_set_encap_proto(struct sk_buff *skb, | |||
331 | struct vlan_hdr *vhdr) | 331 | struct vlan_hdr *vhdr) |
332 | { | 332 | { |
333 | __be16 proto; | 333 | __be16 proto; |
334 | unsigned char *rawp; | 334 | unsigned short *rawp; |
335 | 335 | ||
336 | /* | 336 | /* |
337 | * Was a VLAN packet, grab the encapsulated protocol, which the layer | 337 | * Was a VLAN packet, grab the encapsulated protocol, which the layer |
@@ -344,8 +344,8 @@ static inline void vlan_set_encap_proto(struct sk_buff *skb, | |||
344 | return; | 344 | return; |
345 | } | 345 | } |
346 | 346 | ||
347 | rawp = skb->data; | 347 | rawp = (unsigned short *)(vhdr + 1); |
348 | if (*(unsigned short *) rawp == 0xFFFF) | 348 | if (*rawp == 0xFFFF) |
349 | /* | 349 | /* |
350 | * This is a magic hack to spot IPX packets. Older Novell | 350 | * This is a magic hack to spot IPX packets. Older Novell |
351 | * breaks the protocol design and runs IPX over 802.3 without | 351 | * breaks the protocol design and runs IPX over 802.3 without |