Subject: kern/33216: taggged VLAN packets are seen when they should not
To: None <kern-bug-people@netbsd.org, gnats-admin@netbsd.org,>
From: Pavel Cahyna <pcah8322@artax.karlin.mff.cuni.cz>
List: netbsd-bugs
Date: 04/07/2006 20:35:00
>Number: 33216
>Category: kern
>Synopsis: taggged VLAN packets are seen when they should not
>Confidential: no
>Severity: non-critical
>Priority: medium
>Responsible: kern-bug-people
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Fri Apr 07 20:35:00 +0000 2006
>Originator: Pavel Cahyna
>Release: NetBSD 3.0_RC5
>Organization:
>Environment:
System: NetBSD beta 3.0_RC5 NetBSD 3.0_RC5 (EV56) #3: Mon Dec 12 20:28:20 CET 2005 pavel@beta:/usr/src/sys/arch/alpha/compile/EV56 alpha
Architecture: alpha
Machine: alpha
>Description:
When no VLAN is enabled on an interface which supports HW VLAN tag
insertion and removal, and tagged frames are received, they are
threated as untagged. If a VLAN is enabled, those frames (with a
different VLAN id) are dropped, as they should.
>How-To-Repeat:
Host A has a NIC with HW vlan tagging support.
HostB# ifconfig vlan0 create
HostB# ifconfig vlan0 vlan 4 vlanif fxp0
HostB# ping6 ff02::1%vlan0
PING6(56=40+8+8 bytes) fe80::<HostB>%fxp0 --> ff02::1%fxp0
16 bytes from fe80::<HostB>%vlan0, icmp_seq=0 hlim=64 time=0.151 ms
16 bytes from fe80::<HostA>%fxp0, icmp_seq=0 hlim=64 time=0.504 ms(DUP!)
HostA# ifconfig vlan0 create
HostA# ifconfig vlan0 vlan 5 vlanif gsip0
HostA# ifconfig vlan0 up
HostB# ping6 ff02::1%vlan0
PING6(56=40+8+8 bytes) fe80::<HostB>%fxp0 --> ff02::1%fxp0
16 bytes from fe80::<HostB>%vlan0, icmp_seq=0 hlim=64 time=0.152 ms
(note: no duplicate.)
sys/net/if_ethersubr.c has this code:
if (ec->ec_nvlans && m_tag_find(m, PACKET_TAG_VLAN, NULL) != NULL) {
#if NVLAN > 0
/*
* vlan_input() will either recursively call ether_input()
* or drop the packet.
*/
vlan_input(ifp, m);
#else
m_freem(m);
#endif
return;
}
which lets the tagged frames pass as untagged if ec->ec_nvlans == 0.
>Fix:
(untested) remove the ec->ec_nvlans check, like this:
if (m_tag_find(m, PACKET_TAG_VLAN, NULL) != NULL) {
#if NVLAN > 0
if (ec->ec_nvlans)
/*
* vlan_input() will either recursively call ether_input()
* or drop the packet.
*/
vlan_input(ifp, m);
else
m_freem(m);
#else
m_freem(m);
#endif
return;
}