Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 2 Aug 2006 04:32:23 +0400
From:      Yar Tikhiy <yar@FreeBSD.org>
To:        Qing Li <qingli@FreeBSD.org>
Cc:        cvs-src@FreeBSD.org, sam@FreeBSD.org, src-committers@FreeBSD.org, cvs-all@FreeBSD.org
Subject:   Re: cvs commit: src/sys/net if_vlan.c
Message-ID:  <20060802003223.GA77391@comp.chem.msu.su>
In-Reply-To: <200608011728.k71HSA9m019497@repoman.freebsd.org>
References:  <200608011728.k71HSA9m019497@repoman.freebsd.org>

next in thread | previous in thread | raw e-mail | index | archive | help
On Tue, Aug 01, 2006 at 05:28:10PM +0000, Qing Li wrote:
> qingli      2006-08-01 17:28:10 UTC
> 
>   FreeBSD src repository
> 
>   Modified files:
>     sys/net              if_vlan.c 
>   Log:
>   In vlan_input(), if the network interface does not perform h/w based
>   vlan tag processing, the code will use bcopy() to remove the vlan
>   tag field but the code copies 2 bytes too many, which essentially
>   overwrites the protocol type field.

This had not been true until you removed the line of "dead" code.

>   Also, a tag value of -1 is generated for unrecognized interface type,
>   which would cause an invalid memory access in the vlans[] array.

This is the only part of your change I like in theory, but its
implementation is rather questionable.  See below.

>   In addition, removed a line of dead code and its associated comments.

The code was not dead, you just misunderstood it.  See below.

>   Reviewed by:    sam

I think now I may commit some code Sam didn't dig a couple
of years ago ;-)

>   Revision  Changes    Path
>   1.107     +9 -15     src/sys/net/if_vlan.c

> ===================================================================
> RCS file: /usr/local/www/cvsroot/FreeBSD/src/sys/net/if_vlan.c,v
> retrieving revision 1.106
> retrieving revision 1.107
> diff -u -p -r1.106 -r1.107
> --- src/sys/net/if_vlan.c	2006/07/09 06:04:00	1.106
> +++ src/sys/net/if_vlan.c	2006/08/01 17:28:10	1.107
> @@ -26,7 +26,7 @@
>   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
>   * SUCH DAMAGE.
>   *
> - * $FreeBSD: /usr/local/www/cvsroot/FreeBSD/src/sys/net/if_vlan.c,v 1.106 2006/07/09 06:04:00 sam Exp $
> + * $FreeBSD: /usr/local/www/cvsroot/FreeBSD/src/sys/net/if_vlan.c,v 1.107 2006/08/01 17:28:10 qingli Exp $
>   */
>  
>  /*
> @@ -917,21 +917,15 @@ vlan_input(struct ifnet *ifp, struct mbu
>  				 __func__, ntohs(evl->evl_encap_proto)));
>  
>  			tag = EVL_VLANOFTAG(ntohs(evl->evl_tag));
> -
> -			/*
> -			 * Restore the original ethertype.  We'll remove
> -			 * the encapsulation after we've found the vlan
> -			 * interface corresponding to the tag.
> -			 */
> -			evl->evl_encap_proto = evl->evl_proto;

This "dead" code copied the ethertype value saved in the dot1q
mini-header to the outer Ethernet header's ethertype field. I.e.:

                        +---------------+
                        V               |
+---------+---------+--------+-------+--------+-----------
|   dst   |   src   | proto1 |  tag  | proto0 | payload...
+---------+---------+--------+-------+--------+-----------

Then the outer Ethernet header was as before VLAN encapsulation.
That was why we could bcopy full ETHER_HDR_LEN bytes later.

>  			break;
>  		default:
> -			tag = (uint16_t) -1;
> -#ifdef INVARIANTS
> -			panic("%s: unsupported if_type (%u)",
> -			      __func__, ifp->if_type);
> +#ifdef DEBUG
> +			/* XXX rate limit? */
> +			if_printf(ifp, "unsupported if_type %u", ifp->if_type);
>  #endif

Do you see this message on your console so often that you think it
needs rate limiting?  The former code paniced here because it could
be reached only due to a programming error elsewhere.  See ether_demux()
in if_ethersubr.c and vlan_config() in this file.  This default
case can never be reached due to a bogus frame coming from the
network.

> -			break;
> +			m_freem(m);
> +			ifp->if_noproto++;	/* XXX? */

Nothing wrong with using if_noproto here IMHO, but this still "just
can't happen".

> +			return;
>  		}
>  	}
>  
> @@ -952,12 +946,12 @@ vlan_input(struct ifnet *ifp, struct mbu
>  	if (mtag == NULL) {
>  		/*
>  		 * Packet had an in-line encapsulation header;
> -		 * remove it.  The original header has already
> -		 * been fixed up above.
> +		 * remove it.  Note that we leave the type field
> +		 * unchanged; we only copy up the mac addresses.
>  		 */
>  		bcopy(mtod(m, caddr_t),
>  		      mtod(m, caddr_t) + ETHER_VLAN_ENCAP_LEN,
> -		      ETHER_HDR_LEN);
> +		      ETHER_HDR_LEN - ETHER_TYPE_LEN);
>  		m_adj(m, ETHER_VLAN_ENCAP_LEN);
>  	}

Removing the "dead" assignment to evl->evl_encap_proto above and
reducing the bcopy window by 2 bytes here is a nano-optimization.
Which is worse, it smuggles hidden dot1q details in this otherwise
encapsulation-neutral block of code.  E.g., I could use the former
code for both dot1q and ISL privately by just redefining
ETHER_VLAN_ENCAP_LEN.

Grand total:  I would greately appreciate if you backed out this
change and then fixed the tag value of -1 alone, but let me review
that first.  Thanks!

-- 
Yar



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