An mbuf_outbound_finalize bug that's *not* byte-order related?
site_archiver@lists.apple.com Delivered-To: darwin-kernel@lists.apple.com 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! /*! . . . I built with this entry and ran. Kevin Brock apple@kevin.com _______________________________________________ Do not post admin requests to the list. They will be ignored. Darwin-kernel mailing list (Darwin-kernel@lists.apple.com) Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/darwin-kernel/site_archiver%40lists.a... On Jan 2, 2007, at 10:45 AM, Bhavesh Davda wrote: 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; } 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? This email sent to site_archiver@lists.apple.com
participants (1)
-
Kevin Brock