Subject: Re: IPF 4.1.6 -- NFS Client hangs
To: None <current-users@netbsd.org>
From: Juergen Hannken-Illjes <hannken@eis.cs.tu-bs.de>
List: current-users
Date: 03/06/2005 12:17:59
On Sat, Mar 05, 2005 at 08:03:36PM -0500, Christos Zoulas wrote:
> In article <20050305232215.GA27924@bseis.eis.cs.tu-bs.de>,
> Juergen Hannken-Illjes  <hannken@eis.cs.tu-bs.de> wrote:
> >On Sat, Mar 05, 2005 at 11:50:07AM -0500, Christos Zoulas wrote:
> >> In article <20050305160956.GA20856@bseis.eis.cs.tu-bs.de>,
> >> Juergen Hannken-Illjes  <hannken@eis.cs.tu-bs.de> wrote:
> >> >
> >> >Since IPFilter was upgraded to 4.1.6 on Feb 19, 2005 I get NFS
> >> >client errors `nfs server XXX: not responding' after some time.
> >> >
> >> >I tracked it down to sys/dist/ipf/netinet/fil.c::frpr_udpcommon().
> >> >If I remove the `frpr_pullup()' call all goes well.
> >> >
> >> >Does it ring any bells?
> >> 
> >> Well, the code to handle pullups has been re-written, but the change you
> >> are proposing will break things. The pullup should not fail in the udp
> >> case... Can you add some printfs in the code and see why it frpr_pullup fails?
> >
> >`frpr_pullup()' calls `fr_pullup()' and here the `m = m_pullup(m, len);'
> >sets `m' to NULL (len is 28, M_LEN() is 24).  After ~10 failures the
> >nfs server is declared dead.
> 
> But isn't plen sizeof(udphdr_t) = 2 * 4 = 8? Where does 28 come from?
> The old code capped the fr_pullup to:
> 
> 	up = MIN(hlen + plen, len);
> 
> clearly this is not happening now

The 28 comes from `frpr_pullup() :: plen += fin->fin_hlen;'. This function
and the interesting values are appended.

-- 
Juergen Hannken-Illjes - hannken@eis.cs.tu-bs.de - TU Braunschweig (Germany)

static INLINE int frpr_pullup(fin, plen)
fr_info_t *fin;
int plen;
{
/* fin == 0xc08f4cd0 (always!), plen == 8 */
	if (fin->fin_m != NULL) {
		if (fin->fin_dp != NULL) {
			plen += (char *)fin->fin_dp -
				((char *)fin->fin_ip + fin->fin_hlen);
/* plen == 8 */
		}
		plen += fin->fin_hlen;
/* plen == 28 */
		if (M_LEN(fin->fin_m) < plen) {
/* M_LEN(fin->fin_m) == 24, plen == 28 */
			if (fr_pullup(fin->fin_m, fin, plen) == NULL) {
/* fail */
				return -1;
			}
		}
	}
	return 0;
}