An mbuf_outbound_finalize bug that's *not* byte-order related?
An mbuf_outbound_finalize bug that's *not* byte-order related?
- Subject: An mbuf_outbound_finalize bug that's *not* byte-order related?
- From: Kevin Brock <email@hidden>
- Date: Mon, 22 Jan 2007 18:04:14 -0800
On Jan 2, 2007, at 10:45 AM, Bhavesh Davda wrote:
I don't know why mbuf_outbound_finalize *only* on these packets was
leaving the mbuf trashed, but I have a feeling it has to do with the
mbuf pull-up code in in_delayed_cksum_offset, and the fact that these
mDNS mbufs are chained mbufs, with the pkthdr mbuf containing the L2
header, and the rest of the IP+UDP+payload packet in the next mbuf in
the chain.
So I suspect mbuf_outbound_finalize is probably broken for all chained
mbufs where the pkthdr mbuf doesn't contain the IP header, but I can't
point you to the line of code in the xnu/bsd source that is the
culprit, sorry!
On a dual processor G5 I end up with a kernel panic if I call
mbuf_outbound_finalize on a packet with multiple non-external-data
mbufs. The distinguishing feature of these chains is that the IP
header is not in the same mbuf as the MAC header. In a chain that
has data in external buffers the MAC header and the IP header appear
to be in the same buffer. When the IP header isn't in the first mbuf
mbuf_outbound_finalize calls mbuf_pullup to get everything in one
buffer...
I recently ran into a bug where calling mbuf_pullup on 10.4.8 appears
to cause the mbuf to be freed if the mbuf is multiple non-external-
data mbufs, but doesn't return an error code--I was going to ask the
list about that one when I ran across this problem. Finally stopped
trying to get the IP header into the first buffer, and walked the
chain to find it instead. Unfortunately there's no way I can tell
mbuf_outbound_finalize to do that :-(
There's no byte order problem on G*, and I wanted to eliminate other
code as a possible problem, so I stripped the interface filter output
entry down to:
/*!
. . .
@result Return:
0 - The caller will continue with normal processing of the packet.
EJUSTRETURN - The caller will stop processing the packet, the
packet will not be freed.
Anything Else - The caller will free the packet and stop processing.
*/
errno_t filter_output(void* cookie, ifnet_t interface,
protocol_family_t protocol, mbuf_t *data)
{
mbuf_outbound_finalize(*data, PF_INET, ETHER_HDR_LEN);
return 0;
}
I built with this entry and ran.
Pinging with small packets is fine. I get a panic if I simply say
ping -s 200 <some address>. The actual limit for not crashing is
actually ping -s 160, which fills a single mbuf's data buffer.
This example code works fine on multiple other systems, G4, and G5
(single processor).
The only difference I noticed from the G4 and G5 systems that work is
that the G5 Dual Power Mac that crashes has flags MBUF_CSUM_REQ_IP
and MBUF_CSUM_REQ_UDP or MBUF_CSUM_REQ_TCP set. So on the only
system where this code will actually *do* anything, it's crashing...
The kernel panic says "freeing freed mbuf". This looks *exactly*
like the crashes I was seeing when I called mbuf_pullup. No error
code, but the mbuf appears to have been freed...
Is there some obscure (or obvious) problem with the stripped down
code above?
Kevin Brock
email@hidden
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Darwin-kernel mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden