From nobody@FreeBSD.org  Thu Nov  2 00:35:20 2006
Return-Path: <nobody@FreeBSD.org>
Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125])
	by hub.freebsd.org (Postfix) with ESMTP id C19AB16A49E
	for <freebsd-gnats-submit@FreeBSD.org>; Thu,  2 Nov 2006 00:35:20 +0000 (UTC)
	(envelope-from nobody@FreeBSD.org)
Received: from www.freebsd.org (www.freebsd.org [216.136.204.117])
	by mx1.FreeBSD.org (Postfix) with ESMTP id EFBEB43D64
	for <freebsd-gnats-submit@FreeBSD.org>; Thu,  2 Nov 2006 00:35:06 +0000 (GMT)
	(envelope-from nobody@FreeBSD.org)
Received: from www.freebsd.org (localhost [127.0.0.1])
	by www.freebsd.org (8.13.1/8.13.1) with ESMTP id kA20Z6s9056585
	for <freebsd-gnats-submit@FreeBSD.org>; Thu, 2 Nov 2006 00:35:06 GMT
	(envelope-from nobody@www.freebsd.org)
Received: (from nobody@localhost)
	by www.freebsd.org (8.13.1/8.13.1/Submit) id kA20Z6Ii056584;
	Thu, 2 Nov 2006 00:35:06 GMT
	(envelope-from nobody)
Message-Id: <200611020035.kA20Z6Ii056584@www.freebsd.org>
Date: Thu, 2 Nov 2006 00:35:06 GMT
From: Ian<yoitsmeremember@users.sourceforge.net>
To: freebsd-gnats-submit@FreeBSD.org
Subject: vge driver sends VLAN IDs in wrong endian.
X-Send-Pr-Version: www-3.0

>Number:         105054
>Category:       kern
>Synopsis:       [vge] [patch] vge driver sends VLAN IDs in wrong endian.
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    ru
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Thu Nov 02 00:40:21 GMT 2006
>Closed-Date:    Sun Dec 03 07:16:26 GMT 2006
>Last-Modified:  Sun Dec  3 07:20:04 GMT 2006
>Originator:     Ian
>Release:        6.2-PRERELEASE
>Organization:
none
>Environment:
FreeBSD pillbox 6.2-PRERELEASE FreeBSD 6.2-PRERELEASE #0: Wed Nov  1 15:48:21 CST 2006     root@abomination:/usr/obj/usr/src/sys/MINIMAL  i386
>Description:
The Via Gigabit Ethernet driver, vge(4), sends VLAN IDs (VID) in the incorrect endian.  This not only causes frames to be tagged with the wrong VID, but causes the VID field to bleed into the other fields in the 802.1Q header (Priority and CFI bits).  This does _not_ affect incoming VIDs, which are handled correctly.
>How-To-Repeat:
Ensure the vge driver is compiled into your kernel, and that you have a vge card.  Create a VLAN using ifconfig, and give it an IP address (e.g. `ifconfig vlan291 create inet 10.0.0.1/8 vlan 291 vlandev vge0`).  Connect the interface to another ethernet card via a crossover cable, and sniff traffic, making sure you capture the 802.1Q header (which should appear as 0x0123 in NBO [big endian], assuming you're using vlan 291 with frame with a priority of 0 and the CFI bit unset).  Attempt to ping another IP address on the VLAN's subnet (e.g. `ping 10.0.0.2`), which should generate ARP traffic on the interface.  The 802.1Q header should come through as 0x2301 (little endian, due to the bug).
>Fix:
Patch information for /usr/src/sys/dev/vge/if_vge.c version:
$FreeBSD: src/sys/dev/vge/if_vge.c,v 1.14.2.8 2006/09/05 07:06:15 mr Exp $


*** 1819,1825 ****
  	mtag = VLAN_OUTPUT_TAG(sc->vge_ifp, m_head);
  	if (mtag != NULL)
  		sc->vge_ldata.vge_tx_list[idx].vge_ctl |=
! 		    htole32(htons(VLAN_TAG_VALUE(mtag)) | VGE_TDCTL_VTAG);
  
  	sc->vge_ldata.vge_tx_list[idx].vge_sts |= htole32(VGE_TDSTS_OWN);
  
--- 1819,1825 ----
  	mtag = VLAN_OUTPUT_TAG(sc->vge_ifp, m_head);
  	if (mtag != NULL)
  		sc->vge_ldata.vge_tx_list[idx].vge_ctl |=
! 		    htole32(htole16(VLAN_TAG_VALUE(mtag)) | VGE_TDCTL_VTAG);
  
  	sc->vge_ldata.vge_tx_list[idx].vge_sts |= htole32(VGE_TDSTS_OWN);
  

>Release-Note:
>Audit-Trail:

From: Ruslan Ermilov <ru@FreeBSD.org>
To: Ian <yoitsmeremember@users.sourceforge.net>
Cc: bug-followup@FreeBSD.org
Subject: Re: kern/105054: vge driver sends VLAN IDs in wrong endian.
Date: Thu, 2 Nov 2006 16:58:31 +0300

 --jL2BoiuKMElzg3CS
 Content-Type: text/plain; charset=us-ascii
 Content-Disposition: inline
 Content-Transfer-Encoding: quoted-printable
 
 I looked at the VIA provided Linux driver sources, and it appears that
 VTAG should be inserted in little-endian.
 
 Unfortunately, your suggested fix is incorrect.  Please try the following
 patch instead (pick up the right version) and report back.
 
 This is for RELENG_6:
 
 %%%
 Index: if_vge.c
 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
 RCS file: /home/ncvs/src/sys/dev/vge/if_vge.c,v
 retrieving revision 1.14.2.8
 diff -u -p -r1.14.2.8 if_vge.c
 --- if_vge.c	5 Sep 2006 07:06:15 -0000	1.14.2.8
 +++ if_vge.c	2 Nov 2006 13:40:02 -0000
 @@ -1490,8 +1490,7 @@ vge_rxeof(sc)
  		}
 =20
  		if (rxstat & VGE_RDSTS_VTAG) {
 -			VLAN_INPUT_TAG_NEW(ifp, m,
 -			    ntohs((rxctl & VGE_RDCTL_VLANID)));
 +			VLAN_INPUT_TAG_NEW(ifp, m, rxctl & VGE_RDCTL_VLANID);
  			if (m =3D=3D NULL)
  				continue;
  		}
 @@ -1819,7 +1818,7 @@ vge_encap(sc, m_head, idx)
  	mtag =3D VLAN_OUTPUT_TAG(sc->vge_ifp, m_head);
  	if (mtag !=3D NULL)
  		sc->vge_ldata.vge_tx_list[idx].vge_ctl |=3D
 -		    htole32(htons(VLAN_TAG_VALUE(mtag)) | VGE_TDCTL_VTAG);
 +		    htole32((uint16_t)VLAN_TAG_VALUE(mtag) | VGE_TDCTL_VTAG);
 =20
  	sc->vge_ldata.vge_tx_list[idx].vge_sts |=3D htole32(VGE_TDSTS_OWN);
 =20
 %%%
 
 This is for HEAD:
 
 %%%
 Index: if_vge.c
 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
 RCS file: /home/ncvs/src/sys/dev/vge/if_vge.c,v
 retrieving revision 1.26
 diff -u -p -r1.26 if_vge.c
 --- if_vge.c	17 Sep 2006 13:33:29 -0000	1.26
 +++ if_vge.c	2 Nov 2006 13:41:51 -0000
 @@ -1490,8 +1490,7 @@ vge_rxeof(sc)
  		}
 =20
  		if (rxstat & VGE_RDSTS_VTAG) {
 -			m->m_pkthdr.ether_vtag =3D
 -			    ntohs((rxctl & VGE_RDCTL_VLANID));
 +			m->m_pkthdr.ether_vtag =3D rxctl & VGE_RDCTL_VLANID;
  			m->m_flags |=3D M_VLANTAG;
  		}
 =20
 @@ -1816,7 +1815,7 @@ vge_encap(sc, m_head, idx)
 =20
  	if (m_head->m_flags & M_VLANTAG)
  		sc->vge_ldata.vge_tx_list[idx].vge_ctl |=3D
 -		    htole32(htons(m_head->m_pkthdr.ether_vtag) | VGE_TDCTL_VTAG);
 +		    htole32(m_head->m_pkthdr.ether_vtag | VGE_TDCTL_VTAG);
 =20
  	sc->vge_ldata.vge_tx_list[idx].vge_sts |=3D htole32(VGE_TDSTS_OWN);
 =20
 %%%
 
 
 Cheers,
 --=20
 Ruslan Ermilov
 ru@FreeBSD.org
 FreeBSD committer
 
 --jL2BoiuKMElzg3CS
 Content-Type: application/pgp-signature
 Content-Disposition: inline
 
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1.4.5 (FreeBSD)
 
 iD8DBQFFSfmHqRfpzJluFF4RAvf0AJ9QVxk5QHLDcX4amiO3cANwablO+QCcDOTi
 fhfE2wnkrEoV7cNLzb3SaXU=
 =IpyW
 -----END PGP SIGNATURE-----
 
 --jL2BoiuKMElzg3CS--

From: Yo Its Me Remember <yoitsmeremember@yahoo.com>
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/105054: vge driver sends VLAN IDs in wrong endian.
Date: Thu, 2 Nov 2006 08:59:48 -0800 (PST)

 --0-1761971943-1162486788=:81955
 Content-Type: text/plain; charset=iso-8859-1
 Content-Transfer-Encoding: 8bit
 
 No, the input VLAN tags are fine, as I mentioned in the description.  Your patch changes them so that they're now in big endian instead of little endian, causing another bug.  As far as casting to a uint16_t instead of using htole16, I would think big endian systems would still need to hand the card output tags in little endian.  Not really sure though since I don't have any big endian systems to test it.
 
 Either way, the second half of the patch will work just fine for little endian systems, just leave the input tag ntohs() there.
 
 Thanks,
     Ian
 
  
 ---------------------------------
 Get your email and see which of your friends are online - Right on the  new Yahoo.com
 --0-1761971943-1162486788=:81955
 Content-Type: text/html; charset=iso-8859-1
 Content-Transfer-Encoding: 8bit
 
 No, the input VLAN tags are fine, as I mentioned in the description.&nbsp; Your patch changes them so that they're now in big endian instead of little endian, causing another bug.&nbsp; As far as casting to a uint16_t instead of using htole16, I would think big endian systems would still need to hand the card output tags in little endian.&nbsp; Not really sure though since I don't have any big endian systems to test it.<br><br>Either way, the second half of the patch will work just fine for little endian s ystems, just leave the input tag ntohs() there.<br><br>Thanks,<br>&nbsp;&nbsp;&nbsp; Ian<br><p>&#32;
 
 <hr size=1>Get your email and see which of your friends are online - Right on the <a href="http://us.rd.yahoo.com/evt=42973/*http://www.yahoo.com/preview"> new Yahoo.com</a>
 
 --0-1761971943-1162486788=:81955--

From: Ruslan Ermilov <ru@FreeBSD.org>
To: Yo Its Me Remember <yoitsmeremember@yahoo.com>
Cc: bug-followup@FreeBSD.org
Subject: Re: kern/105054: vge driver sends VLAN IDs in wrong endian.
Date: Thu, 2 Nov 2006 21:34:19 +0300

 On Thu, Nov 02, 2006 at 05:00:40PM +0000, Yo Its Me Remember wrote:
 > No, the input VLAN tags are fine, as I mentioned in the description.
 > Your patch changes them so that they're now in big endian instead
 > of little endian, causing another bug.  As far as casting to a
 > uint16_t instead of using htole16, I would think big endian systems
 > would still need to hand the card output tags in little endian.
 > Not really sure though since I don't have any big endian systems
 > to test it.
 >  
 > Either way, the second half of the patch will work just fine for
 > little endian systems, just leave the input tag ntohs() there.
 >  
 The datasheet is silent on this, and the VIA provided Linux driver
 only has partial support for hardware VLAN tagging (the output part).
 
 If what you say is true, that must be a "strange" chip design -- it
 expects the data in little-endian, but places it in big-endian.
 I'd have to find the hardware in question to confirm this...
 
 
 Cheers,
 -- 
 Ruslan Ermilov
 ru@FreeBSD.org
 FreeBSD committer

From: Yo Its Me Remember <yoitsmeremember@yahoo.com>
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/105054: [vge] [patch] vge driver sends VLAN IDs in wrong endian.
Date: Thu, 2 Nov 2006 13:43:34 -0800 (PST)

 --0-15573433-1162503814=:18302
 Content-Type: text/plain; charset=iso-8859-1
 Content-Transfer-Encoding: 8bit
 
 Yeah, I thought it was pretty strange too, but it's up and running with my patch.  However, now that i think about it, htole16() shouldn't be there, since we're doing bitwise OR we should just leave them both in their native endians and then let the htole32() convert the final product to the correct (little) endian.  Only affects big-endian systems, but would end up causing the same bug that we're trying to fix on them.  Coinsidentally, the original code would work fine on big-endian systems. ;)
 
 If no one on the FBSD team has a vge card, I'd be more than happy to donate money to buy one (they're ~$15 shipped).  Or perhaps we could ask VIA for details...
 
 The final patch that I have working (and should work for big-endian systems) looks like this:
 
 
 *** 1819,1825 ****
          mtag = VLAN_OUTPUT_TAG(sc->vge_ifp, m_head);
          if (mtag != NULL)
                  sc->vge_ldata.vge_tx_list[idx].vge_ctl |=
 !                    htole32(htons(VLAN_TAG_VALUE(mtag)) | VGE_TDCTL_VTAG);
          sc->vge_ldata.vge_tx_list[idx].vge_sts |= htole32(VGE_TDSTS_OWN);
 --- 1819,1825 ----
          mtag = VLAN_OUTPUT_TAG(sc->vge_ifp, m_head);
          if (mtag != NULL)
                  sc->vge_ldata.vge_tx_list[idx].vge_ctl |=
 !                    htole32(VLAN_TAG_VALUE(mtag) | VGE_TDCTL_VTAG);
          sc->vge_ldata.vge_tx_list[idx].vge_sts |= htole32(VGE_TDSTS_OWN);
 ...looks similar for HEAD, just strip out that one htons() on that line.
 
 Thanks,
 Ian
 
  
 ---------------------------------
 Low, Low, Low Rates! Check out Yahoo! Messenger's cheap  PC-to-Phone call rates.
 --0-15573433-1162503814=:18302
 Content-Type: text/html; charset=iso-8859-1
 Content-Transfer-Encoding: 8bit
 
 Yeah, I thought it was pretty strange too, but it's up and running with my patch.&nbsp; However, now that i think about it, htole16() shouldn't be there, since we're doing bitwise OR we should just leave them both in their native endians and then let the htole32() convert the final product to the correct (little) endian.&nbsp; Only affects big-endian systems, but would end up causing the same bug that we're trying to fix on them.&nbsp; Coinsidentally, the original code would work fine on big-endian systems . ;)<br><br>If no one on the FBSD team has a vge card, I'd be more than happy to donate money to buy one (they're ~$15 shipped).&nbsp; Or perhaps we could ask VIA for details...<br><br>The final patch that I have working (and should work for big-endian systems) looks like this:<br><br><pre><span class="patch_revinfo">*** 1819,1825 ****</span><br>         mtag = VLAN_OUTPUT_TAG(sc-&gt;vge_ifp, m_head);<br>         if (mtag != NULL)<br>                
  sc-&gt;vge_ldata.vge_tx_list[idx].vge_ctl |=<br><span class="patch_contextline">!                    htole32(htons(VLAN_TAG_VALUE(mtag)) | VGE_TDCTL_VTAG);</span><br>         sc-&gt;vge_ldata.vge_tx_list[idx].vge_sts |= htole32(VGE_TDSTS_OWN);<br><span class="patch_revinfo">--- 1819,1825 ----</span><br>         mtag = VLAN_OUTPUT_TAG(sc-&gt;vge_ifp, m_head);<br>         if (mtag != NULL)<br>                 sc-&gt;vge_ldata.vge_tx_list[idx].vge_ctl |=<br><span class="patch_contextline">!                     htole32(VLAN_TAG_VALUE(mtag) | VGE_TDCTL_VTAG);</span><br>         sc-&gt;vge_ldata.vge_tx_list[idx].vge_sts |= htole32(VGE_TDSTS_OWN);</pre>...looks similar for HEAD, just strip out that one htons() on that line.<br><br>Thanks,<br>Ian<br><p>&#32;
 
 <hr size=1>Low, Low, Low Rates! Check out Yahoo! Messenger's cheap <a href="http://us.rd.yahoo.com/mail_us/taglines/postman8/*http://us.rd.yahoo.com/evt=39663/*http://voice.yahoo.com"> PC-to-Phone call rates.</a>
 
 --0-15573433-1162503814=:18302--
State-Changed-From-To: open->patched 
State-Changed-By: ru 
State-Changed-When: Thu Nov 30 21:02:11 UTC 2006 
State-Changed-Why:  
Fixed in 7.0-CURRENT. 


Responsible-Changed-From-To: freebsd-bugs->ru 
Responsible-Changed-By: ru 
Responsible-Changed-When: Thu Nov 30 21:02:11 UTC 2006 
Responsible-Changed-Why:  

http://www.freebsd.org/cgi/query-pr.cgi?pr=105054 

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/105054: commit references a PR
Date: Thu, 30 Nov 2006 21:02:56 +0000 (UTC)

 ru          2006-11-30 21:01:59 UTC
 
   FreeBSD src repository
 
   Modified files:
     sys/dev/vge          if_vge.c 
   Log:
   Fix the hardware VLAN tagging.  TX was broken on little-endian
   machines and both TX and RX were broken on big-endian machines.
   
   The chip design is crazy -- on RX, it puts the 16-bit VLAN tag
   in network byte order (big-endian) in the 32-bit little-endian
   register!
   
   Thanks to John Baldwin for helping me document this change! ;-)
   
   Tested by:      sat (amd64), test program (sparc64)
   PR:             kern/105054
   MFC after:      3 days
   
   Revision  Changes    Path
   1.28      +7 -2      src/sys/dev/vge/if_vge.c
 _______________________________________________
 cvs-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/cvs-all
 To unsubscribe, send any mail to "cvs-all-unsubscribe@freebsd.org"
 
State-Changed-From-To: patched->closed 
State-Changed-By: ru 
State-Changed-When: Sun Dec 3 07:16:08 UTC 2006 
State-Changed-Why:  
Fixed in RELENG_6. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=105054 

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/105054: commit references a PR
Date: Sun,  3 Dec 2006 07:16:07 +0000 (UTC)

 ru          2006-12-03 07:15:49 UTC
 
   FreeBSD src repository
 
   Modified files:        (Branch: RELENG_6)
     sys/dev/vge          if_vge.c 
   Log:
   MFC: 1.28: Fix the hardware VLAN tagging.
   
   PR:             kern/105054
   
   Revision  Changes    Path
   1.14.2.9  +7 -2      src/sys/dev/vge/if_vge.c
 _______________________________________________
 cvs-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/cvs-all
 To unsubscribe, send any mail to "cvs-all-unsubscribe@freebsd.org"
 
>Unformatted:
