commit 578fdd2ba59536223e435f57f42ec9cae833d2ef Author: Andrey V. Elsukov Date: Tue Jan 26 14:22:27 2016 +0300 Teach m_get2() reserve max_hdr bytes at the beginning of mbuf. diff --git a/sys/arm/at91/if_ate.c b/sys/arm/at91/if_ate.c index 4497611..21e56cc 100644 --- a/sys/arm/at91/if_ate.c +++ b/sys/arm/at91/if_ate.c @@ -911,14 +911,12 @@ ate_intr(void *xsc) remain = (sc->rx_descs[idx].status & ETH_LEN_MASK) - 4; /* Get an appropriately sized mbuf. */ - mb = m_get2(remain + ETHER_ALIGN, M_NOWAIT, MT_DATA, - M_PKTHDR); + mb = m_get2(remain, M_NOWAIT, MT_DATA, M_PKTHDR); if (mb == NULL) { if_inc_counter(sc->ifp, IFCOUNTER_IQDROPS, 1); rxdhead->status = 0; continue; } - mb->m_data += ETHER_ALIGN; mb->m_pkthdr.rcvif = ifp; WR4(sc, ETH_RSR, RD4(sc, ETH_RSR)); /* Reset status */ diff --git a/sys/dev/usb/wlan/if_rsu.c b/sys/dev/usb/wlan/if_rsu.c index 89b8c00..19f068a 100644 --- a/sys/dev/usb/wlan/if_rsu.c +++ b/sys/dev/usb/wlan/if_rsu.c @@ -1172,7 +1172,6 @@ rsu_event_survey(struct rsu_softc *sc, uint8_t *buf, int len) memcpy(&wh[1], (uint8_t *)&bss[1], le32toh(bss->ieslen)); /* Finalize mbuf. */ - m->m_pkthdr.len = m->m_len = pktlen; m->m_pkthdr.rcvif = ifp; /* Fix the channel. */ c = ieee80211_find_channel_byieee(ic, @@ -1389,7 +1388,6 @@ rsu_rx_frame(struct rsu_softc *sc, uint8_t *buf, int pktlen, int *rssi) } wh = (struct ieee80211_frame *)((uint8_t *)&stat[1] + infosz); memcpy(mtod(m, uint8_t *), wh, pktlen); - m->m_pkthdr.len = m->m_len = pktlen; if (ieee80211_radiotap_active(ic)) { struct rsu_rx_radiotap_header *tap = &sc->sc_rxtap; diff --git a/sys/kern/uipc_mbuf.c b/sys/kern/uipc_mbuf.c index a249add..5bf2037 100644 --- a/sys/kern/uipc_mbuf.c +++ b/sys/kern/uipc_mbuf.c @@ -131,11 +131,8 @@ CTASSERT(sizeof(m_assertbuf.m_slistpkt) == sizeof(m_assertbuf.m_nextpkt)); CTASSERT(sizeof(m_assertbuf.m_stailqpkt) == sizeof(m_assertbuf.m_nextpkt)); #endif -/* - * m_get2() allocates minimum mbuf that would fit "size" argument. - */ -struct mbuf * -m_get2(int size, int how, short type, int flags) +static struct mbuf * +m_get2_internal(int size, int how, short type, int flags) { struct mb_args args; struct mbuf *m, *n; @@ -165,6 +162,36 @@ m_get2(int size, int how, short type, int flags) } /* + * m_get2() allocates minimum mbuf that would fit "size" argument. + * Also m_len and m_pkthdr.len will be set to the "size" value. + * NOTE: if M_PKTHDR flag is present, in addition to specified "size" + * argument m_get2 will reserve the leading space equal to max_hdr. + */ +struct mbuf * +m_get2(int size, int how, short type, int flags) +{ + struct mbuf *m; + + m = m_get2_internal(size + + ((flags & M_PKTHDR) ? max_hdr: 0), how, type, flags); + + if (m == NULL) + return (NULL); + m->m_len = size; + if ((flags & M_PKTHDR) != 0) { + /* + * We have allocated size + max_hdr bytes, now use + * m_align() to set m_data pointer to place an object of + * the requested size at the end of the mbuf. Thus max_hdr + * bytes will remain at the beginning of the mbuf. + */ + m_align(m, size); + m->m_pkthdr.len = size; + } + return (m); +} + +/* * m_getjcl() returns an mbuf with a cluster of the specified size attached. * For size it takes MCLBYTES, MJUMPAGESIZE, MJUM9BYTES, MJUM16BYTES. */ diff --git a/sys/kern/uipc_syscalls.c b/sys/kern/uipc_syscalls.c index e3557ba..271b7c3 100644 --- a/sys/kern/uipc_syscalls.c +++ b/sys/kern/uipc_syscalls.c @@ -1759,7 +1759,6 @@ sockargs(mp, buf, buflen, type) return (EINVAL); } m = m_get2(buflen, M_WAITOK, type, 0); - m->m_len = buflen; error = copyin(buf, mtod(m, caddr_t), (u_int)buflen); if (error != 0) (void) m_free(m); diff --git a/sys/net/bpf.c b/sys/net/bpf.c index 9fc5e9f..1d9d922 100644 --- a/sys/net/bpf.c +++ b/sys/net/bpf.c @@ -542,7 +542,6 @@ bpf_movein(struct uio *uio, int linktype, struct ifnet *ifp, struct mbuf **mp, m = m_get2(len, M_WAITOK, MT_DATA, M_PKTHDR); if (m == NULL) return (EIO); - m->m_pkthdr.len = m->m_len = len; *mp = m; error = uiomove(mtod(m, u_char *), len, uio); diff --git a/sys/netinet/libalias/alias.c b/sys/netinet/libalias/alias.c index bd36604..03628b4 100644 --- a/sys/netinet/libalias/alias.c +++ b/sys/netinet/libalias/alias.c @@ -1759,12 +1759,9 @@ m_megapullup(struct mbuf *m, int len) { mcl = m_get2(len, M_NOWAIT, MT_DATA, M_PKTHDR); if (mcl == NULL) goto bad; - m_align(mcl, len); m_move_pkthdr(mcl, m); m_copydata(m, 0, len, mtod(mcl, caddr_t)); - mcl->m_len = mcl->m_pkthdr.len = len; - m_freem(m); - + m_freem(m); /* XXX: what to do when len < m_pkthdr.len? */ return (mcl); bad: m_freem(m); diff --git a/sys/netipsec/key.c b/sys/netipsec/key.c index 34e8c41..6122b7c 100644 --- a/sys/netipsec/key.c +++ b/sys/netipsec/key.c @@ -1618,7 +1618,6 @@ key_sp2msg(struct secpolicy *sp) if (m == NULL) return (NULL); m_align(m, tlen); - m->m_len = tlen; xpl = mtod(m, struct sadb_x_policy *); bzero(xpl, tlen); @@ -1703,7 +1702,6 @@ key_gather_mbuf(struct mbuf *m, const struct sadb_msghdr *mhp, if (n == NULL) goto fail; m_align(n, len); - n->m_len = len; m_copydata(m, mhp->extoff[idx], mhp->extlen[idx], mtod(n, caddr_t)); } else { @@ -2570,7 +2568,6 @@ key_spdexpire(struct secpolicy *sp) goto fail; } m_align(m, len); - m->m_len = len; bzero(mtod(m, caddr_t), len); lt = mtod(m, struct sadb_lifetime *); lt->sadb_lifetime_len = PFKEY_UNIT64(sizeof(struct sadb_lifetime)); @@ -3547,7 +3544,6 @@ key_setsadbsa(struct secasvar *sav) if (m == NULL) return (NULL); m_align(m, len); - m->m_len = len; p = mtod(m, struct sadb_sa *); bzero(p, len); p->sadb_sa_len = PFKEY_UNIT64(len); @@ -3579,7 +3575,6 @@ key_setsadbaddr(u_int16_t exttype, const struct sockaddr *saddr, if (m == NULL) return (NULL); m_align(m, len); - m->m_len = len; p = mtod(m, struct sadb_address *); bzero(p, len); @@ -3623,7 +3618,6 @@ key_setsadbxsa2(u_int8_t mode, u_int32_t seq, u_int32_t reqid) if (m == NULL) return (NULL); m_align(m, len); - m->m_len = len; p = mtod(m, struct sadb_x_sa2 *); bzero(p, len); @@ -3655,7 +3649,6 @@ key_setsadbxtype(u_int16_t type) if (m == NULL) return (NULL); m_align(m, len); - m->m_len = len; p = mtod(m, struct sadb_x_nat_t_type *); bzero(p, len); @@ -3682,7 +3675,6 @@ key_setsadbxport(u_int16_t port, u_int16_t type) if (m == NULL) return (NULL); m_align(m, len); - m->m_len = len; p = mtod(m, struct sadb_x_nat_t_port *); bzero(p, len); @@ -3757,7 +3749,6 @@ key_setsadbxpolicy(u_int16_t type, u_int8_t dir, u_int32_t id) if (m == NULL) return (NULL); m_align(m, len); - m->m_len = len; p = mtod(m, struct sadb_x_policy *); bzero(p, len); @@ -6811,7 +6802,6 @@ key_expire(struct secasvar *sav, int hard) goto fail; } m_align(m, len); - m->m_len = len; bzero(mtod(m, caddr_t), len); lt = mtod(m, struct sadb_lifetime *); lt->sadb_lifetime_len = PFKEY_UNIT64(sizeof(struct sadb_lifetime)); @@ -7794,7 +7784,6 @@ key_setkey(struct seckey *src, u_int16_t exttype) if (m == NULL) return NULL; m_align(m, len); - m->m_len = len; p = mtod(m, struct sadb_key *); bzero(p, len); p->sadb_key_len = PFKEY_UNIT64(len); @@ -7833,7 +7822,6 @@ key_setlifetime(struct seclifetime *src, u_int16_t exttype) if (m == NULL) return m; m_align(m, len); - m->m_len = len; p = mtod(m, struct sadb_lifetime *); bzero(p, len); diff --git a/sys/netpfil/pf/if_pfsync.c b/sys/netpfil/pf/if_pfsync.c index 516a92a..b23b5df 100644 --- a/sys/netpfil/pf/if_pfsync.c +++ b/sys/netpfil/pf/if_pfsync.c @@ -1523,14 +1523,12 @@ pfsync_sendout(int schedswi) return; } - m = m_get2(max_linkhdr + sc->sc_len, M_NOWAIT, MT_DATA, M_PKTHDR); + m = m_get2(sc->sc_len, M_NOWAIT, MT_DATA, M_PKTHDR); if (m == NULL) { if_inc_counter(sc->sc_ifp, IFCOUNTER_OERRORS, 1); V_pfsyncstats.pfsyncs_onomem++; return; } - m->m_data += max_linkhdr; - m->m_len = m->m_pkthdr.len = sc->sc_len; /* build the ip header */ ip = (struct ip *)m->m_data; diff --git a/sys/nfs/krpc_subr.c b/sys/nfs/krpc_subr.c index 2d37c108..e24cf2d 100644 --- a/sys/nfs/krpc_subr.c +++ b/sys/nfs/krpc_subr.c @@ -461,7 +461,6 @@ xdr_string_encode(char *str, int len) m = m_get2(mlen, M_WAITOK, MT_DATA, 0); xs = mtod(m, struct xdr_string *); - m->m_len = mlen; xs->len = txdr_unsigned(len); bcopy(str, xs->data, len); return (m);