- Use m_getcl() instead of hand allocating.

- Do not calculate constant length values at run time,
  CTASSERT() their sanity.
- Remove superfluous cleaning of mbuf fields after allocation.
- Replace compat macros with function calls.

Sponsored by:	Nginx, Inc.
This commit is contained in:
Gleb Smirnoff 2013-03-15 13:48:53 +00:00
parent 3c26f4a9bc
commit 10e5acc3c6
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=248328
4 changed files with 51 additions and 104 deletions

View File

@ -578,25 +578,18 @@ icmp6_input(struct mbuf **mp, int *offp, int proto)
if ((n->m_flags & M_EXT) != 0
|| n->m_len < off + sizeof(struct icmp6_hdr)) {
struct mbuf *n0 = n;
const int maxlen = sizeof(*nip6) + sizeof(*nicmp6);
int n0len;
CTASSERT(sizeof(*nip6) + sizeof(*nicmp6) <= MHLEN);
n = m_gethdr(M_NOWAIT, n0->m_type);
n0len = n0->m_pkthdr.len; /* save for use below */
if (n)
M_MOVE_PKTHDR(n, n0); /* FIB copied. */
if (n && maxlen >= MHLEN) {
MCLGET(n, M_NOWAIT);
if ((n->m_flags & M_EXT) == 0) {
m_free(n);
n = NULL;
}
}
if (n == NULL) {
/* Give up remote */
m_freem(n0);
break;
}
m_move_pkthdr(n, n0); /* FIB copied. */
n0len = n0->m_pkthdr.len; /* save for use below */
/*
* Copy IPv6 and ICMPv6 only.
*/
@ -683,7 +676,7 @@ icmp6_input(struct mbuf **mp, int *offp, int proto)
} else {
struct prison *pr;
u_char *p;
int maxlen, maxhlen, hlen;
int maxhlen, hlen;
/*
* XXX: this combination of flags is pointless,
@ -694,20 +687,14 @@ icmp6_input(struct mbuf **mp, int *offp, int proto)
if (code != 0)
goto badcode;
maxlen = sizeof(*nip6) + sizeof(*nicmp6) + 4;
if (maxlen >= MCLBYTES) {
CTASSERT(sizeof(*nip6) + sizeof(*nicmp6) + 4 <= MHLEN);
n = m_gethdr(M_NOWAIT, m->m_type);
if (n == NULL) {
/* Give up remote */
break;
}
n = m_gethdr(M_NOWAIT, m->m_type);
if (n && maxlen > MHLEN) {
MCLGET(n, M_NOWAIT);
if ((n->m_flags & M_EXT) == 0) {
m_free(n);
n = NULL;
}
}
if (n && !m_dup_pkthdr(n, m, M_NOWAIT)) {
if (!m_dup_pkthdr(n, m, M_NOWAIT)) {
/*
* Previous code did a blind M_COPY_PKTHDR
* and said "just for rcvif". If true, then
@ -718,13 +705,8 @@ icmp6_input(struct mbuf **mp, int *offp, int proto)
m_free(n);
n = NULL;
}
if (n == NULL) {
/* Give up remote */
break;
}
n->m_pkthdr.rcvif = NULL;
n->m_len = 0;
maxhlen = M_TRAILINGSPACE(n) - maxlen;
maxhlen = M_TRAILINGSPACE(n) -
(sizeof(*nip6) + sizeof(*nicmp6) + 4);
pr = curthread->td_ucred->cr_prison;
mtx_lock(&pr->pr_mtx);
hlen = strlen(pr->pr_hostname);
@ -1494,26 +1476,23 @@ ni6_input(struct mbuf *m, int off)
break;
}
/* allocate an mbuf to reply. */
n = m_gethdr(M_NOWAIT, m->m_type);
/* Allocate an mbuf to reply. */
if (replylen > MCLBYTES) {
/*
* XXX: should we try to allocate more? But MCLBYTES
* is probably much larger than IPV6_MMTU...
*/
goto bad;
}
if (replylen > MHLEN)
n = m_getcl(M_NOWAIT, m->m_type, M_PKTHDR);
else
n = m_gethdr(M_NOWAIT, m->m_type);
if (n == NULL) {
m_freem(m);
return (NULL);
}
M_MOVE_PKTHDR(n, m); /* just for recvif and FIB */
if (replylen > MHLEN) {
if (replylen > MCLBYTES) {
/*
* XXX: should we try to allocate more? But MCLBYTES
* is probably much larger than IPV6_MMTU...
*/
goto bad;
}
MCLGET(n, M_NOWAIT);
if ((n->m_flags & M_EXT) == 0) {
goto bad;
}
}
m_move_pkthdr(n, m); /* just for recvif and FIB */
n->m_pkthdr.len = n->m_len = replylen;
/* copy mbuf header and IPv6 + Node Information base headers */

View File

@ -506,7 +506,7 @@ ip6_input(struct mbuf *m)
return; /* ENOBUFS */
}
M_MOVE_PKTHDR(n, m);
m_move_pkthdr(n, m);
m_copydata(m, 0, n->m_pkthdr.len, mtod(n, caddr_t));
n->m_len = n->m_pkthdr.len;
m_freem(m);
@ -1662,23 +1662,13 @@ ip6_pullexthdr(struct mbuf *m, size_t off, int nxt)
else
elen = (ip6e.ip6e_len + 1) << 3;
MGET(n, M_NOWAIT, MT_DATA);
if (n && elen >= MLEN) {
MCLGET(n, M_NOWAIT);
if ((n->m_flags & M_EXT) == 0) {
m_free(n);
n = NULL;
}
}
if (!n)
if (elen > MLEN)
n = m_getcl(M_NOWAIT, MT_DATA, 0);
else
n = m_get(M_NOWAIT, MT_DATA);
if (n == NULL)
return NULL;
n->m_len = 0;
if (elen >= M_TRAILINGSPACE(n)) {
m_free(n);
return NULL;
}
m_copydata(m, off, elen, mtod(n, caddr_t));
n->m_len = elen;
return n;

View File

@ -1219,17 +1219,12 @@ ip6_copyexthdr(struct mbuf **mp, caddr_t hdr, int hlen)
if (hlen > MCLBYTES)
return (ENOBUFS); /* XXX */
MGET(m, M_NOWAIT, MT_DATA);
if (!m)
if (hlen > MLEN)
m = m_getcl(M_NOWAIT, MT_DATA, 0);
else
m = m_get(M_NOWAIT, MT_DATA);
if (m == NULL)
return (ENOBUFS);
if (hlen > MLEN) {
MCLGET(m, M_NOWAIT);
if ((m->m_flags & M_EXT) == 0) {
m_free(m);
return (ENOBUFS);
}
}
m->m_len = hlen;
if (hdr)
bcopy(hdr, mtod(m, caddr_t), hlen);
@ -1257,8 +1252,8 @@ ip6_insert_jumboopt(struct ip6_exthdrs *exthdrs, u_int32_t plen)
* Otherwise, use it to store the options.
*/
if (exthdrs->ip6e_hbh == 0) {
MGET(mopt, M_NOWAIT, MT_DATA);
if (mopt == 0)
mopt = m_get(M_NOWAIT, MT_DATA);
if (mopt == NULL)
return (ENOBUFS);
mopt->m_len = JUMBOOPTLEN;
optbuf = mtod(mopt, u_char *);
@ -1289,15 +1284,8 @@ ip6_insert_jumboopt(struct ip6_exthdrs *exthdrs, u_int32_t plen)
* As a consequence, we must always prepare a cluster
* at this point.
*/
MGET(n, M_NOWAIT, MT_DATA);
if (n) {
MCLGET(n, M_NOWAIT);
if ((n->m_flags & M_EXT) == 0) {
m_freem(n);
n = NULL;
}
}
if (!n)
n = m_getcl(M_NOWAIT, MT_DATA, 0);
if (n == NULL)
return (ENOBUFS);
n->m_len = oldoptlen + JUMBOOPTLEN;
bcopy(mtod(mopt, caddr_t), mtod(n, caddr_t),
@ -1366,8 +1354,8 @@ ip6_insertfraghdr(struct mbuf *m0, struct mbuf *m, int hlen,
/* allocate a new mbuf for the fragment header */
struct mbuf *mfrg;
MGET(mfrg, M_NOWAIT, MT_DATA);
if (mfrg == 0)
mfrg = m_get(M_NOWAIT, MT_DATA);
if (mfrg == NULL)
return (ENOBUFS);
mfrg->m_len = sizeof(struct ip6_frag);
*frghdrp = mtod(mfrg, struct ip6_frag *);
@ -3047,7 +3035,7 @@ ip6_splithdr(struct mbuf *m, struct ip6_exthdrs *exthdrs)
m_freem(m);
return ENOBUFS;
}
M_MOVE_PKTHDR(mh, m);
m_move_pkthdr(mh, m);
MH_ALIGN(mh, sizeof(*ip6));
m->m_len -= sizeof(*ip6);
m->m_data += sizeof(*ip6);

View File

@ -419,17 +419,12 @@ nd6_ns_output(struct ifnet *ifp, const struct in6_addr *daddr6,
return;
}
MGETHDR(m, M_NOWAIT, MT_DATA);
if (m && max_linkhdr + maxlen >= MHLEN) {
MCLGET(m, M_NOWAIT);
if ((m->m_flags & M_EXT) == 0) {
m_free(m);
m = NULL;
}
}
if (max_linkhdr + maxlen > MHLEN)
m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
else
m = m_gethdr(M_NOWAIT, MT_DATA);
if (m == NULL)
return;
m->m_pkthdr.rcvif = NULL;
bzero(&ro, sizeof(ro));
@ -997,17 +992,12 @@ nd6_na_output_fib(struct ifnet *ifp, const struct in6_addr *daddr6_0,
return;
}
MGETHDR(m, M_NOWAIT, MT_DATA);
if (m && max_linkhdr + maxlen >= MHLEN) {
MCLGET(m, M_NOWAIT);
if ((m->m_flags & M_EXT) == 0) {
m_free(m);
m = NULL;
}
}
if (max_linkhdr + maxlen > MHLEN)
m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
else
m = m_gethdr(M_NOWAIT, MT_DATA);
if (m == NULL)
return;
m->m_pkthdr.rcvif = NULL;
M_SETFIB(m, fibnum);
if (IN6_IS_ADDR_MULTICAST(&daddr6)) {