Minor hack in the netgraph interface to ethernets.
This commit is contained in:
parent
cfbcfe6272
commit
021823c35c
@ -1133,29 +1133,78 @@ bad:
|
||||
|
||||
/*
|
||||
* pass an mbuf out to the connected hook
|
||||
*/
|
||||
* More complicated than just an m_prepend, as it tries to save later nodes
|
||||
* from needing to do lots of m_pullups.
|
||||
*/
|
||||
static void
|
||||
ngether_send(struct arpcom *ac, struct ether_header *eh, struct mbuf *m)
|
||||
{
|
||||
{
|
||||
int room;
|
||||
node_p node = AC2NG(ac);
|
||||
struct ether_header *eh2;
|
||||
|
||||
|
||||
if (node && LIST_FIRST(&(node->hooks))) {
|
||||
M_PREPEND(m, sizeof(*eh), M_DONTWAIT);
|
||||
if (m == 0)
|
||||
return;
|
||||
eh2 = mtod(m, struct ether_header *);
|
||||
/*
|
||||
* Possibly 'eh' already points
|
||||
* to the right place.
|
||||
* Possibly the header is already on the front,
|
||||
*/
|
||||
if (eh2 != eh)
|
||||
bcopy(eh, eh2, sizeof(*eh));
|
||||
eh2 = mtod(m, struct ether_header *) - 1;
|
||||
if ( eh == eh2) {
|
||||
/*
|
||||
* This is the case so just move the markers back to
|
||||
* re-include it. We lucked out.
|
||||
* This allows us to avoid a yucky m_pullup
|
||||
* in later nodes if it works.
|
||||
*/
|
||||
m->m_len += sizeof(*eh);
|
||||
m->m_data -= sizeof(*eh);
|
||||
m->m_pkthdr.len += sizeof(*eh);
|
||||
} else {
|
||||
/*
|
||||
* Alternatively there may be room even though
|
||||
* it is stored somewhere else. If so, copy it in.
|
||||
* This only safe because we KNOW that this packet has
|
||||
* just been generated by an ethernet card, so there
|
||||
* are no aliases to the buffer. (unlike in outgoing
|
||||
* packets).
|
||||
* Nearly all ethernet cards will end up producing mbufs
|
||||
* that fall into these cases. So we are not optimising
|
||||
* contorted cases.
|
||||
*/
|
||||
|
||||
if (m->m_flags & M_EXT) {
|
||||
room = (mtod(m, caddr_t) - m->m_ext.ext_buf);
|
||||
if (room > m->m_ext.ext_size) /* garbage */
|
||||
room = 0; /* fail immediatly */
|
||||
} else {
|
||||
room = (mtod(m, caddr_t) - m->m_pktdat);
|
||||
}
|
||||
if (room > sizeof (*eh)) {
|
||||
/* we have room, just copy it and adjust */
|
||||
m->m_len += sizeof(*eh);
|
||||
m->m_data -= sizeof(*eh);
|
||||
m->m_pkthdr.len += sizeof(*eh);
|
||||
bcopy ((caddr_t)eh, (caddr_t)eh2, sizeof(*eh));
|
||||
} else {
|
||||
/*
|
||||
* Doing anything more is likely to get more
|
||||
* expensive than it's worth..
|
||||
* it's probable that everything else is in one
|
||||
* big lump. The next node will do an m_pullup()
|
||||
* for exactly the amount of data it needs and
|
||||
* hopefully everything after that will not
|
||||
* need one. So let's just use m_prepend.
|
||||
*/
|
||||
m = m_prepend(m, MHLEN, M_DONTWAIT);
|
||||
if (m == NULL)
|
||||
return;
|
||||
}
|
||||
}
|
||||
ng_queue_data(LIST_FIRST(&(node->hooks)), m, NULL);
|
||||
} else {
|
||||
m_freem(m);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* do local shutdown processing..
|
||||
* This node will refuse to go away, unless the hardware says to..
|
||||
|
Loading…
x
Reference in New Issue
Block a user