| From | Sent On | Attachments |
|---|---|---|
| Greg Lehey | Jun 20, 1996 11:03 am | |
| Nate Williams | Jun 20, 1996 11:45 am | |
| Dennis | Jun 20, 1996 2:06 pm | |
| David Greenman | Jun 20, 1996 2:43 pm | |
| Greg Lehey | Jun 21, 1996 12:50 am | |
| Greg Lehey | Jun 21, 1996 6:36 am | |
| Oleg N Panashchenko | Jun 21, 1996 10:03 am | |
| Greg Lehey | Jun 22, 1996 4:16 am | |
| David Greenman | Jun 22, 1996 5:33 pm |
| Subject: | Re: IP question: who should return ENOBUFS? | |
|---|---|---|
| From: | David Greenman (dav...@root.com) | |
| Date: | Jun 20, 1996 2:43:38 pm | |
| List: | org.freebsd.freebsd-hackers | |
=== 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





