Date: Thu, 20 Jun 1996 14:43:58 -0700 From: David Greenman <davidg@root.com> To: grog@lemis.de (Greg Lehey) Cc: hackers@freebsd.org (FreeBSD Hackers) Subject: Re: IP question: who should return ENOBUFS? Message-ID: <199606202143.OAA01814@root.com> In-Reply-To: Your message of "Thu, 20 Jun 1996 20:03:32 %2B0200." <199606201803.UAA19421@allegro.lemis.de>
next in thread | previous in thread | raw e-mail | index | archive | help
>=== 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 > >I found this strange, since in the interface code (b_isdnipi.c, line >474) we have the code: > > if (IF_QFULL(&ifp->if_snd)) > { > if (ifp->if_flags & IFF_RUNNING) > isdn_output(sc->sc_appl); > IF_DROP(&ifp->if_snd); > m_freem(m); > splx(x); > ifp->if_oerrors++; > return (ENOBUFS); > } > >This will drop the first packet *and* not enqueue the last if the >queue is full. So I set a breakpoint on the IF_DROP, and hey! nothing >happened. 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? The interface has no knowledge of whether or not this is a fragment in a mulitple fragment datagram. FreeBSD is very good about keeping the output queue of an interface busy. Allowing any one of the fragments that make up an IP packet to be dropped makes the entire packet useless. The above piece of code fixes a bug where the output queue is kept completely full, and each time that the second fragment of a packet is queued it is dropped. This results eventually in the need to retransmit it and the same thing happens again. That in itself isn't so much of a problem except that in the process of doing this, you're flooding the network with useless fragments and getting nowhere in the process. The only way to fix this is to drop all of the fragments of a fragmented packet and the only place you can do this is before the packet is fragmented. The above is only a problem for UDP. TCP's window prevents the queue limit from being reached in usual case. -DG David Greenman Core-team/Principal Architect, The FreeBSD Project
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199606202143.OAA01814>