From owner-freebsd-hackers Thu Jun 20 11:12:32 1996 Return-Path: owner-hackers Received: (from root@localhost) by freefall.freebsd.org (8.7.5/8.7.3) id LAA28493 for hackers-outgoing; Thu, 20 Jun 1996 11:12:32 -0700 (PDT) Received: from diablo.ppp.de (diablo.ppp.de [193.141.101.34]) by freefall.freebsd.org (8.7.5/8.7.3) with SMTP id LAA28384 for ; Thu, 20 Jun 1996 11:11:12 -0700 (PDT) Received: from allegro.lemis.de by diablo.ppp.de with smtp (Smail3.1.28.1 #1) id m0uWoCB-000QYQC; Thu, 20 Jun 96 20:11 MET DST From: grog@lemis.de (Greg Lehey) Organisation: LEMIS, Schellnhausen 2, 36325 Feldatal, Germany Phone: +49-6637-919123 Fax: +49-6637-919122 Received: (grog@localhost) by allegro.lemis.de (8.6.9/8.6.9) id UAA19421 for hackers@freebsd.org; Thu, 20 Jun 1996 20:03:32 +0200 Message-Id: <199606201803.UAA19421@allegro.lemis.de> Subject: IP question: who should return ENOBUFS? To: hackers@freebsd.org (FreeBSD Hackers) Date: Thu, 20 Jun 1996 20:03:32 +0200 (MET DST) X-Mailer: ELM [version 2.4 PL23] MIME-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 8bit Sender: owner-hackers@freebsd.org X-Loop: FreeBSD.org Precedence: bulk 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 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? Greg