Bug 15303

Summary: Bug in Hardware VLAN Tag Support
Product: Base System Reporter: csg <csg>
Component: kernAssignee: freebsd-bugs (Nobody) <bugs>
Status: Closed FIXED    
Severity: Affects Only Me CC: ajk
Priority: Normal    
Version: 3.3-STABLE   
Hardware: Any   
OS: Any   
Attachments:
Description Flags
file.diff none

Description csg 1999-12-06 14:10:01 UTC
sys/net/if_vlan.c contains support for ethernet hardware that
support tagged VLANs in hardware.  Currently (AFAIK) only the "ti"
driver written by Bill Paul has support for these features.

Apparently, when the ethernet driver detects a tagged frame from the
hardware, it passes the frame, along with the tag to vlan_input_tag()
instead of the normal vlan_input() call from inside ether_input().

The problem arrises in an attempt to log errors on the parent device.
vlan_input_tag() walks the list of vlan devices, looking for a matching
and tries to log the error on the parent device if appropriately.

Unfortunatly, the current code incorrectly assumes that all vlans
are configured, and/or associated with a parent device.  If you 
receive a frame for a VLAN that's not in the list, you walk off
the end of the list.  Boom.

Fix: This patch modifies vlan_input_tag to return -1 in the event of an
error so the parent device can maintain its counters for us.

- BEGIN PATCH -----------------------------------------------------------------

-void
+int
 vlan_input_tag(struct ether_header *eh, struct mbuf *m, u_int16_t t)
 {
        int i;
@@ -284,10 +284,9 @@
                        break;
        }

-       if (i >= NVLAN || (ifv->ifv_if.if_flags & IFF_UP) == 0) {
-               m_freem(m);
-               ifv->ifv_p->if_data.ifi_noproto++;
-               return;
+       if (i >= NVLAN) {
+               m_free(m);
+               return -1;      /* So the parent can take note */
        }

        /*
@@ -312,7 +311,7 @@
        }
        ifv->ifv_if.if_ipackets++;
        ether_input(&ifv->ifv_if, eh, m);
-       return;
+       return 0;
 }

 int


- END PATCH -------------------------------------------------------------------


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-net" in the body of the message--6F3NN7yGjp4B8eKS6Fx18WWJXxbs40IcUjOQsZLdSRckEWZC
Content-Type: text/plain; name="file.diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="file.diff"

Index: pci/if_ti.c
===================================================================
RCS file: /usr/local/share/cvs/FreeBSD/src/sys/pci/if_ti.c,v
retrieving revision 1.24
diff -u -r1.24 if_ti.c
--- if_ti.c     1999/09/23 03:32:54     1.24
+++ if_ti.c     1999/12/05 22:28:44
@@ -1887,7 +1887,8 @@
                 * to vlan_input() instead of ether_input().
                 */
                if (have_tag) {
-                       vlan_input_tag(eh, m, vlan_tag);
+                       if (vlan_input_tag(eh, m, vlan_tag) < 0)
+                               ifp->if_data.ifi_noproto++;
                        have_tag = vlan_tag = 0;
                        continue;
                }
Index: if_vlan.c
===================================================================
RCS file: /usr/local/share/cvs/FreeBSD/src/sys/net/if_vlan.c,v
retrieving revision 1.10
diff -u -r1.10 if_vlan.c
--- if_vlan.c   1999/09/25 12:05:57     1.10
+++ if_vlan.c   1999/12/06 00:17:05
@@ -272,7 +272,7 @@
        return;
 }
How-To-Repeat: 
1. Setup a host with multiple VLAN's on an 802.1Q trunk to the machine,
   with a ti0 ethernet interface.

2. Configure some but not all of the vlan interfaces:

   # ifconfig <parent-device> up
   # ifconfig vlan0 vlandev <parent-device> vlan <tag-number 1>
   # ifconfig vlan1 vlandev <parent-device> vlan <tag-number 2>
 
3. Wait for traffic on an as-of-yet unconfigured vlan number.

4. Watch your machine crashdump..
Comment 1 csg 1999-12-06 18:31:24 UTC
Oops.  Looks like my laptop crash ended up sending two copies
of this PR.  Please ignore this duplicate report.

 - Steve
Comment 2 Sheldon Hearn freebsd_committer freebsd_triage 1999-12-07 14:57:31 UTC
State Changed
From-To: open->closed

Duplicate of PR 15291.