Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 20 Jun 1996 17:07:08 -0400
From:      dennis@etinc.com (Dennis)
To:        Nate Williams <nate@sri.MT.net>
Cc:        hackers@freebsd.org
Subject:   Re: IP question: who should return ENOBUFS?
Message-ID:  <199606202107.RAA08181@etinc.com>

next in thread | raw e-mail | index | archive | help
>I Cc'd David on this since I'm not sure he reads hackers, and he's
>responsible for the piece of code in question.
>
>> I've just spent a fair amount of time trying to figure out why our
>> ISDN software jams up if it can't establish a connection.  The
>> symptoms are that if you can't establish a connection before a certain
>> number of packets have been sent, the whole interface just returns:
>> 
>> === root@freebie (/dev/ttyp0) /sys/netinet 11 -> ping 192.109.197.38
>> PING 192.109.197.38 (192.109.197.38): 56 data bytes
>> ping: sendto: No buffer space available
>> ping: wrote 192.109.197.38 64 chars, ret=-1
>> ping: sendto: No buffer space available
>....
>
>.  After a bit more investigation, I found this code in
>> ip_output.c:
>> 
>> 	/*
>> 	 * Verify that we have any chance at all of being able to queue
>> 	 *      the packet or packet fragments
>> 	 */
>> 	if ((ifp->if_snd.ifq_len + ip->ip_len / ifp->if_mtu + 1) >=
>> 		ifp->if_snd.ifq_maxlen) {
>> 			error = ENOBUFS;
>> 			goto bad;
>> 	}
>> 
>> I think this is bogus.  It's not present in the BSD/OS version, so I
>> assume it was added in FreeBSD.  The problem is, it gives you no
>> possibility of recovery: the queue is full and stays that way.  Can
>> anybody give me an idea of why it's there, when the interface is
>> perfectly capable of looking after itself?
>
>Here's the log messages when David made the change.
>
>----------------------------
>revision 1.3
>date: 1994/08/01 12:01:45;  author: davidg;  state: Exp;  lines: +10 -0
>fixed bug where large amounts of unidirectional UDP traffic would fill
>the interface output queue and further udp packets would be fragmented
>and only partially sent - keeping the output queue full and jamming the
>network, but not actually getting any real work done (because you can't
>send just 'part' of a udp packet - if you fragment it, you must send
>the whole thing). The fix involves adding a check to make sure that the
>output queue has sufficient space for all of the fragments.

ENOBUFS  causes a QUENCH to be sent, which is arguably correct
if the problem is truly a queue overload. This should not "break" the 
connection unless the source is broken. ICMP ignores the return
value from ip_output, so it should not matter what is returned.
 
Another problem is that you need queue management based on the available
bandwidth of the interface. You can't have the same management 
scheme or thresholds for a 10Mbs interface as you do for a 56kbs one.

This is precisely why we have the interface manage the queue depth. 
Additionally, queue managment should be based on queue size in bits
(or bytes), not number of packets. 100 60 byte packets is not backup...
100 1000 byte packets is. Using packet counts is simply wrong.

Dennis
----------------------------------------------------------------------------
Emerging Technologies, Inc.      http://www.etinc.com

Synchronous Communications Cards and Routers For
Discriminating Tastes. 56k to T1 and beyond. Frame
Relay, PPP, HDLC, and X.25 for BSD/OS, FreeBSD 
and LINUX




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199606202107.RAA08181>