Subject: Re: misc problems
To: Jeff Weisberg <jaw@magoo.roc.ny.us>
From: Chuck Cranor <chuck@maria.wustl.edu>
List: port-sun3
Date: 01/23/1995 11:41:53
>|    Do you have an "ie" ethernet interface, and do you have UDP checksums
>| turned on on the server?    We just discovered last night that the 
>| solaris 2.x NFS server is dropping the packets due to UDP checksums.

>Nope (le) and nope it is turned off.  

Ok, so your problem is unrelated to the trouble we've been having
with the "ie" driver.  Oh well....

Anyway, John Stone (@umr.edu) and I discovered the problem with the 
"ie" driver while working on the sun-4/110 port.  When I ported the 
"ie" driver to the sparc from the i386 port I inherited this:

#define IE_TBUF_SIZE    1512    /* length of transmit buffer */

This value is wrong.  It should be 1514 (1500 (ETHERMTU) + 6 byte source +
6 byte dest + 2 byte type field).

This only caused problems when you sent large packets back to back
(e.g. NFS write's).   In that case the copy loop in if_ie.c would copy
off the edge of the transmit buffer into the next item (in one case
the other transmit buffer, in the other case a receive buffer).
[the copy loop had a check to prevent this, but it was buggy too]

The result was that if you had UDP checksums off, your NFS writes 
would be corrupt.  If you had UDP checksums on, writes the filesystem 
would hang the machine (if diskless).

This needs to be fixed in both the sun3 and sparc ports.  (it may
need fixing in the i386 port as well?)

cheers,
chuck

ps- here is a sparc patch:
*** if_ie.c_ORIG	Mon Jan 23 10:19:03 1995
--- if_ie.c	Mon Jan 23 11:05:19 1995
***************
*** 171,177 ****
  #define	MXRXBUF (MXFRAMES*B_PER_F)	/* max number of buffers to allocate */
  #define	IE_RBUF_SIZE	256	/* size of each buffer, MUST BE POWER OF TWO */
  #define	NTXBUF		2	/* number of transmit buffer/command pairs */
! #define	IE_TBUF_SIZE	1512	/* length of transmit buffer */
  
  
  enum ie_hardware {
--- 171,177 ----
  #define	MXRXBUF (MXFRAMES*B_PER_F)	/* max number of buffers to allocate */
  #define	IE_RBUF_SIZE	256	/* size of each buffer, MUST BE POWER OF TWO */
  #define	NTXBUF		2	/* number of transmit buffer/command pairs */
! #define	IE_TBUF_SIZE	1514	/* length of transmit buffer */
  
  
  enum ie_hardware {
***************
*** 1382,1392 ****
  		buffer = sc->xmit_cbuffs[sc->xmit_count];
  		len = 0;
  
! 		for (m0 = m; m && len < IE_TBUF_SIZE; m = m->m_next) {
  			(sc->memcopy)(mtod(m, caddr_t), buffer, m->m_len);
  			buffer += m->m_len;
  			len += m->m_len;
  		}
  
  		m_freem(m0);
  		len = max(len, ETHER_MIN_LEN);
--- 1382,1395 ----
  		buffer = sc->xmit_cbuffs[sc->xmit_count];
  		len = 0;
  
! 		for (m0 = m; m && (len + m->m_len) <= IE_TBUF_SIZE; 
! 							m = m->m_next) {
  			(sc->memcopy)(mtod(m, caddr_t), buffer, m->m_len);
  			buffer += m->m_len;
  			len += m->m_len;
  		}
+ 		if (m) 
+ 			printf("%s: tbuf overflow\n", sc->sc_dev.dv_xname);
  
  		m_freem(m0);
  		len = max(len, ETHER_MIN_LEN);