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:
John-Mark Gurney 2005-03-17 19:34:57 +00:00
parent 7378822d3c
commit 7ac139a904
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=143761
3 changed files with 78 additions and 0 deletions

View File

@ -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

View File

@ -766,6 +766,54 @@ m_pullup(struct mbuf *n, int len)
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

View File

@ -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));