Fri 28 Jan 2011 05:18:48 PM UTC, original submission:
Consider the function pppLinkTerminated()
There is the following line:
pppDrop(&pc->rx); /* bug fix #17726 */
It fixes an ancient bug from the era when the ppp code was very old.
Recently Simon did a great work and ported back the changes from pppd 2.3.1.
I suspect that since then this line is not needed any more.
The problem I see is that an assert fires at the end of pppInput():
"Assertion "pbuf_free: p->ref > 0" failed at line 563 in E:/Work/proj1/lwIP/src/core/pbuf.c"
This happens while I am closing the link when I get a TERM ACK from the peer. When such packet is received
all protocols are lowered down and all ppp timeouts get cancelled. During this ride
pppLinkTerminated() is called too.
Then, after "goto out;" we try to free again the same pbuf, which fires the assertion.
I'm not brave enough to delete the suggested line because I'm not sure that
all paths to pppLinkTerminated go through pppInput(). I prefer to live with the
firing assertion. I added a bit of code just to suppress the firing.
There are no harmful consequences, so this can be left for lwip 1.4.1
Any suggestions what should be done?
static void pppInput(void *arg)
{
.....
switch(protocol) {
.....
default: {
struct protent *protp;
int i;
/*
* Upcall the proper protocol input routine.
*/
for (i = 0; (protp = ppp_protocols[i]) != NULL; ++i) {
if (protp->protocol == protocol && protp->enabled_flag) {
PPPDEBUG(LOG_INFO, ("npppInput[%d]: %s len=%dn", pd, protp->name, nb->len));
nb = pppSingleBuf(nb);
(*protp->input)(pd, nb->payload, nb->len); // here the packet is passed to its handler
PPPDEBUG(LOG_DETAIL, ("pppInput[%d]: packet processedn", pd));
#if 1
if (nb->ref == 0) // if the pbuf is already free-d by LinkTerminated, don't try to free it again
{
goto justreturn;
}
#endif
goto out; // if this is TERMACK, pppDrop has already been called for this pbuf (nb)
}
}
/* No handler for this protocol so reject the packet. */
PPPDEBUG(LOG_INFO, ("pppInput[%d]: rejecting unsupported proto 0x%"X16_F" len=%dn", pd, protocol, nb->len));
if (pbuf_header(nb, sizeof(protocol))) {
LWIP_ASSERT("pbuf_header failedn", 0);
goto drop;
}
.....
}
break;
} // switch
drop:
LINK_STATS_INC(link.drop);
snmp_inc_ifindiscards(&pppControl[pd].netif);
out:
pbuf_free(nb); // Assertion "pbuf_free: p->ref > 0" failed at line 563 in E:/Work/proj1/lwIP/src/core/pbuf.c
justreturn:
return;
}
|