add m_copyup function.. This can be used to help make our ip stack less
alignment restrictive, and help performance on some ethernet cards which currently copy the entire packet a couple bytes to get the packet aligned properly... Wordsmithing by: dwhite Obtained from: NetBSD (code only) I'll clean it up later: rwatson
This commit is contained in:
parent
755ffaa47d
commit
19da85af4a
@ -95,6 +95,8 @@
|
||||
.Ft struct mbuf *
|
||||
.Fn m_prepend "struct mbuf *mbuf" "int len" "int how"
|
||||
.Ft struct mbuf *
|
||||
.Fn m_copyup "struct mbuf *mbuf" "int len" "int dstoff"
|
||||
.Ft struct mbuf *
|
||||
.Fn m_pullup "struct mbuf *mbuf" "int len"
|
||||
.Ft struct mbuf *
|
||||
.Fn m_copym "struct mbuf *mbuf" "int offset" "int len" "int how"
|
||||
@ -614,6 +616,33 @@ depending on the
|
||||
.Dv M_PKTHDR
|
||||
flag setting.
|
||||
.\"
|
||||
.It Fn m_copyup mbuf len dstoff
|
||||
Similar to
|
||||
.Fn m_pullup
|
||||
but copies
|
||||
.Fa len
|
||||
bytes of data into a new mbuf at
|
||||
.Fa dstoff
|
||||
bytes into the mbuf.
|
||||
The
|
||||
.Fa dstoff
|
||||
argument aligns the data and leaves room for a link layer header.
|
||||
Return the new
|
||||
.Vt mbuf chain
|
||||
on success,
|
||||
and frees the
|
||||
.Vt mbuf chain
|
||||
and returns
|
||||
.Dv NULL
|
||||
on failure.
|
||||
.Sy Note :
|
||||
The function does not allocate
|
||||
.Vt mbuf clusters ,
|
||||
so
|
||||
.Fa len + dstoff
|
||||
must be less than
|
||||
.Dv MHLEN .
|
||||
.\"
|
||||
.It Fn m_pullup mbuf len
|
||||
Arrange that the first
|
||||
.Fa len
|
||||
|
@ -766,6 +766,54 @@ bad:
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Like m_pullup(), except a new mbuf is always allocated, and we allow
|
||||
* the amount of empty space before the data in the new mbuf to be specified
|
||||
* (in the event that the caller expects to prepend later).
|
||||
*/
|
||||
int MSFail;
|
||||
|
||||
struct mbuf *
|
||||
m_copyup(struct mbuf *n, int len, int dstoff)
|
||||
{
|
||||
struct mbuf *m;
|
||||
int count, space;
|
||||
|
||||
if (len > (MHLEN - dstoff))
|
||||
goto bad;
|
||||
MGET(m, M_DONTWAIT, n->m_type);
|
||||
if (m == NULL)
|
||||
goto bad;
|
||||
m->m_len = 0;
|
||||
if (n->m_flags & M_PKTHDR)
|
||||
M_MOVE_PKTHDR(m, n);
|
||||
m->m_data += dstoff;
|
||||
space = &m->m_dat[MLEN] - (m->m_data + m->m_len);
|
||||
do {
|
||||
count = min(min(max(len, max_protohdr), space), n->m_len);
|
||||
memcpy(mtod(m, caddr_t) + m->m_len, mtod(n, caddr_t),
|
||||
(unsigned)count);
|
||||
len -= count;
|
||||
m->m_len += count;
|
||||
n->m_len -= count;
|
||||
space -= count;
|
||||
if (n->m_len)
|
||||
n->m_data += count;
|
||||
else
|
||||
n = m_free(n);
|
||||
} while (len > 0 && n);
|
||||
if (len > 0) {
|
||||
(void) m_free(m);
|
||||
goto bad;
|
||||
}
|
||||
m->m_next = n;
|
||||
return (m);
|
||||
bad:
|
||||
m_freem(n);
|
||||
MSFail++;
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Partition an mbuf chain in two pieces, returning the tail --
|
||||
* all but the first len0 bytes. In case of failure, it returns NULL and
|
||||
|
@ -564,6 +564,7 @@ void m_copydata(const struct mbuf *, int, int, caddr_t);
|
||||
struct mbuf *m_copym(struct mbuf *, int, int, int);
|
||||
struct mbuf *m_copypacket(struct mbuf *, int);
|
||||
void m_copy_pkthdr(struct mbuf *, struct mbuf *);
|
||||
struct mbuf *m_copyup(struct mbuf *n, int len, int dstoff);
|
||||
struct mbuf *m_defrag(struct mbuf *, int);
|
||||
struct mbuf *m_devget(char *, int, int, struct ifnet *,
|
||||
void (*)(char *, caddr_t, u_int));
|
||||
|
Loading…
x
Reference in New Issue
Block a user