Re: Networking: mbuf->m_hdr.mh_data doesn't include DLIL header?
Re: Networking: mbuf->m_hdr.mh_data doesn't include DLIL header?
- Subject: Re: Networking: mbuf->m_hdr.mh_data doesn't include DLIL header?
- From: "Bhavesh Davda" <email@hidden>
- Date: Tue, 19 Sep 2006 10:30:13 -0700
I tried this approach, and it doesn't work consistently.
The problem is that not every packet sent to my iff_input_func has the
ethernet header stripped (okay not stripped, but the mbuf_data pointer
points beyond it).
As a result, now I am seeing the ethernet header repeated back to back
for those packets that happened to be delivered with the ethernet
header intact to my iff_input_func.
I need a smarter way to figure out when the kernel is going to strip
the ethernet header when delivering it to my iff_input_func.
Will the following heuristic work consistently?
if (mbuf_data(*packet) != mbuf_pktdat(*packet)) {
// the ethernet drivers must have stripped the L2 header. Prepend it
}
Alternatively, I could compare mbuf_data(*packet) to *frame_ptr passed
into the iff_input_func.
Thanks
- Bhavesh
On 9/18/06, Bhavesh Davda <email@hidden> wrote:
Yuck!
But thanks for the code snippet, Josh! Especially because in the last
few days, I've had to discover the hard way what I should really pass
to mbuf_pkthdr_setheader() as the second parameter :)
Thanks! I'll give this a shot too. Incidentally, my approach also
"works" in the sense that now my cloned mbufs in my NKE do contain the
ethernet header, but as I was afraid, mutating the input mbuf breaks
the stack. I'll try your approach instead.
Thanks
- Bhavesh
On 9/18/06, Josh Graessley <email@hidden> wrote:
>
> The input function is allowed to make modifications.
>
> You will want to leave the packet in the same format you found it
> before you return from the function if you're going to let the packet
> continue up the stack. So something like this would work:
>
> errno_t myFilterInput(ifnet_t interface, protocol_family_t protocol,
> mbuf_t *packet, char **frame_ptr)
> {
> struct ether_header *en_header = (struct ether_header*)*frame_ptr;
>
> /* Prepend the ethernet header */
> errno_t result = mbuf_prepend(packet, sizeof(*en_header), MBUF_WAITOK);
> if (result != 0)
> {
> *packet = NULL;
> return result;
> }
> *((struct ether_header*)mbuf_data(*packet)) = *en_header;
>
> /* Do any work you want here, including calling mbuf_dup */
> result = doSomeWork(packet);
>
> /* Fixup the packet to allow it to continue up the stack */
> if (result == 0 && *packet)
> {
> /* Fixup the original so the packet starts after the ethernet
> header */
> /* This same code should be used before injecting an ethernet
> packet up the stack (ifnet_input). You may also need to set the
> receive interface.
> mbuf_pkthdr_setheader(*packet, mbuf_data(*packet));
> mbuf_adj(*packet, sizeof(*en_header));
> }
>
> return result;
> }
>
> enjoy,
> -josh
>
> On Sep 18, 2006, at 4:17 PM, Bhavesh Davda wrote:
>
> > Thanks for your response, Josh.
> >
> > I was thinking of an alternate workaround:
> >
> > I'm not sure what the kpi_mbuf comment about "data" being something
> > the iff_input_func can modify means, but if it indeed can modify it, I
> > was going to "fix up" the m_data pointer to point to m_pktdat, before
> > cloning the packet via mbuf_dup.
> >
> > The downside of this is that if the "data" parameter is really
> > supposed to be non-mutable, then I've just broken the assumption for
> > the rest of the kernel :(
> >
> > What do you think?
> >
> > Thanks
> >
> > - Bhavesh
> >
> >
> > On 9/18/06, Josh Graessley <email@hidden> wrote:
> >>
> >> The packet header field is a big disaster.
> >>
> >> When an ethernet driver inputs a packet it usually:
> >>
> >> - has the whole packet copied in to the mbuf
> >> - Sets the mbuf's packet header to point to where the ethernet frame
> >> starts in the mbuf
> >> - uses mbuf_adj or something similar to move the start of the mbuf
> >> pointer to the end of the ethernet header
> >>
> >> If you're doing to use mbuf_dup on one of these packets your best bet
> >> is probably to:
> >> - mbuf_prepend for the length of the ethernet header
> >> - copy the ethernet header in to the preceeding space you just
> >> created using mbuf_prepend
> >> - duplicate the packet
> >> - set the packet header's header field to the mbuf_data value
> >> - mbuf_adj for the size of the ethernet header
> >>
> >> If there was one thing I could undo it would be the wacky way in
> >> which this header stuff is handled. It is especially frustrating when
> >> you're working with interface filters. On the outbound path, you get
> >> the entire packet in the mbuf chain. On the inbound path, the
> >> ethernet header is separate, in the packet header's header field. It
> >> usually points to some place in the allocated space for the first
> >> mbuf, but there are no guarantees this will be the case.
> >>
> >> -josh
> >>
> >> On Sep 18, 2006, at 1:46 PM, Bhavesh Davda wrote:
> >>
> >> > For certain packets that my iff_input_func is receiving, when I
> >> looked
> >> > at the entire mbuf structure received in parameter 4, I noticed
> >> that
> >> > the m_hdr.mh_data field offsets 14 bytes beyond the start of the
> >> > ethernet frame.
> >> >
> >> > This is causing my mbuf_dup() cloned mbuf to not contain the 14
> >> bytes
> >> > of ethernet header in my NKE.
> >> >
> >> > Looking in the original mbuf received in my iff_input_func, the 14
> >> > bytes of ethernet header are in the mbuf body at
> >> > mbuf->M_dat.MH.MH_dat.MH_databuf[0..13].
> >> >
> >> > What am I doing wrong? How do I clone the mbuf to include the DLIL
> >> > header?
> >> >
> >> > Thanks!
> >> >
> >> > - Bhavesh
> >> >
> >> > --
> >> > Bhavesh P. Davda
> >> > _______________________________________________
> >> > Do not post admin requests to the list. They will be ignored.
> >> > Darwin-kernel mailing list (email@hidden)
> >> > Help/Unsubscribe/Update your Subscription:
> >> > 40apple.com
> >> >
> >> > This email sent to email@hidden
> >>
> >>
> >>
> >>
> >
> >
> > --
> > Bhavesh P. Davda
>
>
>
>
--
Bhavesh P. Davda
--
Bhavesh P. Davda
_______________________________________________
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