Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 21 Oct 2000 16:04:53 +0400 (MSD)
From:      yar@comp.chem.msu.su
To:        FreeBSD-gnats-submit@freebsd.org
Subject:   kern/22179: VLAN driver fails to hanlde interface flags properly
Message-ID:  <200010211204.e9LC4rv00676@yar.chem.msu.su>

next in thread | raw e-mail | index | archive | help

>Number:         22179
>Category:       kern
>Synopsis:       VLAN driver fails to hanlde interface flags properly
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Sat Oct 21 05:10:01 PDT 2000
>Closed-Date:
>Last-Modified:
>Originator:     Yar Tikhiy
>Release:        FreeBSD 4.1-STABLE i386
>Organization:
Moscow State University
>Environment:

	The bugs show up in all branches.

>Description:

	1. Many network interface drivers' XX_start() routines don't
	   check if an interface is up and running because they rely
	   on upper layers doing that. The vlan_start() routine,
	   which calls XX_start() routines of underlying "parent" drivers,
	   fails to do that, causing system panic when a packet is
           being sent via a vlan interface while its parnet interface
	   is down.

	2. The VLAN driver copies flags from a parent interface to
	   a vlan interface mindlessly. However, setting some flags
	   implies certain additional actions. In particular,
	   bringing an interface up involves setting up a link-layer
	   route to it. The VLAN driver fails to do that because it
	   just copies the bit.

	3. The if_up() and if_down() routines must be called at splnet()
	   or equivalent. They also shouldn't be called if an interface is
	   already up or down, correspondingly, because they do no
	   additional checks. The VLAN driver is not aware of the above.

	   I'd also suggest adding a couple of words on the properties
	   of if_up()/if_down() to the ifnet(9) man page.

>How-To-Repeat:

	1. Try to assign an IP address to a VLAN interface which parent
	   is down and see the system panic due to sending a gratituous
	   ARP through the parent.
	2. Assign a parent and an IP address to a VLAN interface.
	   Then remove the parent with "ifconfig vlanX -vlandev".
	   Then add another (or the same) parent back. See that packets
	   don't go out, because there is no proper link-layer route
	   to the VLAN interface.

>Fix:

--- if_vlan.c.orig	Sat Oct 21 14:13:01 2000
+++ if_vlan.c	Sat Oct 21 15:53:10 2000
@@ -205,6 +205,17 @@
 			bpf_mtap(ifp, m);
 
 		/*
+		 * Do not run parent's if_start() if it's not up,
+		 * or parent's driver will cause a system crash
+		 */
+		if ((p->if_flags & (IFF_UP | IFF_RUNNING)) !=
+					(IFF_UP | IFF_RUNNING)) {
+			m_freem(m);
+			ifp->if_data.ifi_collisions++;
+			continue;
+		}
+
+		/*
 		 * If the LINK0 flag is set, it means the underlying interface
 		 * can do VLAN tag insertion itself and doesn't require us to
 	 	 * create a special header for it. In this case, we just pass
@@ -362,9 +373,10 @@
 		ifv->ifv_if.if_mtu = p->if_data.ifi_mtu - EVL_ENCAPLEN;
 
 	/*
-	 * Preserve the state of the LINK0 flag for ourselves.
+	 * Copy only a selected subset of flags from the parent
 	 */
-	ifv->ifv_if.if_flags = (p->if_flags & ~(IFF_LINK0));
+	ifv->ifv_if.if_flags = (p->if_flags &
+	    (IFF_BROADCAST | IFF_MULTICAST | IFF_SIMPLEX | IFF_POINTOPOINT));
 
 	/*
 	 * Set up our ``Ethernet address'' to reflect the underlying
@@ -488,8 +500,12 @@
 			break;
 		if (vlr.vlr_parent[0] == '\0') {
 			vlan_unconfig(ifp);
-			if_down(ifp);
-			ifp->if_flags &= ~(IFF_UP|IFF_RUNNING);
+			if (ifp->if_flags & IFF_UP) {
+				int s = splimp();
+				if_down(ifp);
+				splx(s);
+			}		
+			ifp->if_flags &= ~IFF_RUNNING;
 			break;
 		}
 		p = ifunit(vlr.vlr_parent);

>Release-Note:
>Audit-Trail:
>Unformatted:


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200010211204.e9LC4rv00676>