Commit d4b812dea4a236f729526facf97df1a9d18e191c
Committed by
David S. Miller
1 parent
ece793fcfc
vlan: mask vlan prio bits
In commit 48cc32d38a52d0b68f91a171a8d00531edc6a46e ("vlan: don't deliver frames for unknown vlans to protocols") Florian made sure we set pkt_type to PACKET_OTHERHOST if the vlan id is set and we could find a vlan device for this particular id. But we also have a problem if prio bits are set. Steinar reported an issue on a router receiving IPv6 frames with a vlan tag of 4000 (id 0, prio 2), and tunneled into a sit device, because skb->vlan_tci is set. Forwarded frame is completely corrupted : We can see (8100:4000) being inserted in the middle of IPv6 source address : 16:48:00.780413 IP6 2001:16d8:8100:4000:ee1c:0:9d9:bc87 > 9f94:4d95:2001:67c:29f4::: ICMP6, unknown icmp6 type (0), length 64 0x0000: 0000 0029 8000 c7c3 7103 0001 a0ae e651 0x0010: 0000 0000 ccce 0b00 0000 0000 1011 1213 0x0020: 1415 1617 1819 1a1b 1c1d 1e1f 2021 2223 0x0030: 2425 2627 2829 2a2b 2c2d 2e2f 3031 3233 It seems we are not really ready to properly cope with this right now. We can probably do better in future kernels : vlan_get_ingress_priority() should be a netdev property instead of a per vlan_dev one. For stable kernels, lets clear vlan_tci to fix the bugs. Reported-by: Steinar H. Gunderson <sesse@google.com> Signed-off-by: Eric Dumazet <edumazet@google.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Showing 3 changed files with 11 additions and 5 deletions Side-by-side Diff
include/linux/if_vlan.h
... | ... | @@ -79,9 +79,8 @@ |
79 | 79 | } |
80 | 80 | |
81 | 81 | #define vlan_tx_tag_present(__skb) ((__skb)->vlan_tci & VLAN_TAG_PRESENT) |
82 | -#define vlan_tx_nonzero_tag_present(__skb) \ | |
83 | - (vlan_tx_tag_present(__skb) && ((__skb)->vlan_tci & VLAN_VID_MASK)) | |
84 | 82 | #define vlan_tx_tag_get(__skb) ((__skb)->vlan_tci & ~VLAN_TAG_PRESENT) |
83 | +#define vlan_tx_tag_get_id(__skb) ((__skb)->vlan_tci & VLAN_VID_MASK) | |
85 | 84 | |
86 | 85 | #if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) |
87 | 86 |
net/8021q/vlan_core.c
net/core/dev.c
... | ... | @@ -3580,8 +3580,15 @@ |
3580 | 3580 | } |
3581 | 3581 | } |
3582 | 3582 | |
3583 | - if (vlan_tx_nonzero_tag_present(skb)) | |
3584 | - skb->pkt_type = PACKET_OTHERHOST; | |
3583 | + if (unlikely(vlan_tx_tag_present(skb))) { | |
3584 | + if (vlan_tx_tag_get_id(skb)) | |
3585 | + skb->pkt_type = PACKET_OTHERHOST; | |
3586 | + /* Note: we might in the future use prio bits | |
3587 | + * and set skb->priority like in vlan_do_receive() | |
3588 | + * For the time being, just ignore Priority Code Point | |
3589 | + */ | |
3590 | + skb->vlan_tci = 0; | |
3591 | + } | |
3585 | 3592 | |
3586 | 3593 | /* deliver only exact match when indicated */ |
3587 | 3594 | null_or_dev = deliver_exact ? skb->dev : NULL; |