net: handle 802.1P vlan 0 packets properly
When stack receives pkt: [802.1P vlan 0][802.1AD vlan 100][IPv4], vlan_do_receive() returns false if it does not find vlan_dev. Later __netif_receive_skb_core() fails to find packet type handler for skb->protocol 801.1AD and drops the packet. 801.1P header with vlan id 0 should be handled as untagged packets. This patch fixes it by checking if vlan_id is 0 and processes next vlan header. Signed-off-by: Govindarajulu Varadarajan <gvaradar@cisco.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
1eb4169c1e
commit
36b2f61a42
|
@ -4923,8 +4923,36 @@ skip_classify:
|
||||||
}
|
}
|
||||||
|
|
||||||
if (unlikely(skb_vlan_tag_present(skb))) {
|
if (unlikely(skb_vlan_tag_present(skb))) {
|
||||||
if (skb_vlan_tag_get_id(skb))
|
check_vlan_id:
|
||||||
|
if (skb_vlan_tag_get_id(skb)) {
|
||||||
|
/* Vlan id is non 0 and vlan_do_receive() above couldn't
|
||||||
|
* find vlan device.
|
||||||
|
*/
|
||||||
skb->pkt_type = PACKET_OTHERHOST;
|
skb->pkt_type = PACKET_OTHERHOST;
|
||||||
|
} else if (skb->protocol == cpu_to_be16(ETH_P_8021Q) ||
|
||||||
|
skb->protocol == cpu_to_be16(ETH_P_8021AD)) {
|
||||||
|
/* Outer header is 802.1P with vlan 0, inner header is
|
||||||
|
* 802.1Q or 802.1AD and vlan_do_receive() above could
|
||||||
|
* not find vlan dev for vlan id 0.
|
||||||
|
*/
|
||||||
|
__vlan_hwaccel_clear_tag(skb);
|
||||||
|
skb = skb_vlan_untag(skb);
|
||||||
|
if (unlikely(!skb))
|
||||||
|
goto out;
|
||||||
|
if (vlan_do_receive(&skb))
|
||||||
|
/* After stripping off 802.1P header with vlan 0
|
||||||
|
* vlan dev is found for inner header.
|
||||||
|
*/
|
||||||
|
goto another_round;
|
||||||
|
else if (unlikely(!skb))
|
||||||
|
goto out;
|
||||||
|
else
|
||||||
|
/* We have stripped outer 802.1P vlan 0 header.
|
||||||
|
* But could not find vlan dev.
|
||||||
|
* check again for vlan id to set OTHERHOST.
|
||||||
|
*/
|
||||||
|
goto check_vlan_id;
|
||||||
|
}
|
||||||
/* Note: we might in the future use prio bits
|
/* Note: we might in the future use prio bits
|
||||||
* and set skb->priority like in vlan_do_receive()
|
* and set skb->priority like in vlan_do_receive()
|
||||||
* For the time being, just ignore Priority Code Point
|
* For the time being, just ignore Priority Code Point
|
||||||
|
|
Loading…
Reference in New Issue