lwip-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

RE: [lwip-devel] Possibly falsely triggered LWIP_ASSERT?


From: Kieran Mansley
Subject: RE: [lwip-devel] Possibly falsely triggered LWIP_ASSERT?
Date: Tue, 29 Sep 2009 14:59:24 +0100

On Tue, 2009-09-29 at 08:56 -0400, Bill Auerbach wrote:
> >The odd bit is that p->next is NULL, so I think the assertion might be
> >noticing a real problem.  You have p->len at 46 and p->tot_len at 1064,
> >so this suggests a chain of pbufs, and we would naturally expect p->next
> >to be the next thing in the chain.  Where exactly is the call being made
> >from ip_input?  The other possibility is it's trying to shrink the tail
> >of the packet, but I can't think off the top of my head why it would
> >want to do that.
> 
> ip_input is called from ethernet_input from netif->input from
> ethernetif_input from my main program loop.
> 
> I'm working on a contrib app with NO_SYS=1, optional DHCP and optional
> http_serverraw with an Ethernet port for Altera TSE/NIOS using the supplied
> ethernetif.c template.  I've using unmodified lwIP and opts.h (copied to
> lwiptopts.h) as unchanged as possible.  For better responsiveness, I changed
> TCP_MSS to 1024 - I think 128 is a value needed only for extreme cases
> (right?).
> 
> I get the assertion when I ping larger than TCP_MSS - because
> PBUF_POOL_BUFSIZE depends on TCP_MSS.

OK, I've had a quick look at the code.  ip_input() calls pbuf_realloc()
to shrink the pbuf down to the size of the IP data.  In your case it
thinks it has been given 1064 bytes but the IP header says there is just
1028 bytes.  I think this has been probably been passed up to the stack
as two chained pbufs, most likely one full one of 1024 and the last 46
bytes in the next pbuf.  Note that these numbers don't quite add up, but
I'm not sure why: they mostly come from your first email.

The stack wants to get rid of the extra data at the end of the packet,
so it needs to shrink the second pbuf in the chain by 36 bytes.  To work
out what to shrink it iterates over the pbufs in the chain in
pbuf_realloc() and finds that it gets to the end of the chain before it
gets to the point it needs to start shrinking.  This probably explains
why the numbers don't add up.

My guess is that pbuf->tot_len for the chain does not match the sum of
pbuf->len for all the pbufs in the chain.

Looking at pbuf_realloc() there is one thing there that worries me:
Line 342:
    q->tot_len += (u16_t)grow;

We're casting grow (which is negative in the shrinking case) to a u16_t.
I think this should be case to a s16_t to preserve the sign of grow, and
correctly handle increasing and decreasing the size.  Does anyone
disagree - if I'm missing something I'd like to know.  This could
explain the problem you're seeing if pbuf_realloc() had been called
earlier on.  It's certainly worth trying with that change.

Kieran





reply via email to

[Prev in Thread] Current Thread [Next in Thread]