diff --git a/sys/dev/netif/age/if_age.c b/sys/dev/netif/age/if_age.c --- a/sys/dev/netif/age/if_age.c +++ b/sys/dev/netif/age/if_age.c @@ -1989,7 +1989,7 @@ struct rx_desc *desc; struct mbuf *mp, *m; uint32_t status, index, vtag; - int count, nsegs, pktlen; + int count, nsegs, pktlen, segsz; int rx_cons; status = le32toh(rxrd->flags); @@ -2021,6 +2021,14 @@ rxd = &sc->age_cdata.age_rxdesc[rx_cons]; mp = rxd->rx_m; desc = rxd->rx_desc; + /* + * Snapshot desc->len BEFORE age_newbuf() recycles the + * descriptor for the next receive (which overwrites + * desc->len). Reading it afterwards yields 0 for every + * non-first segment and corrupts the first mbuf's m_len. + */ + segsz = AGE_RX_BYTES(le32toh(desc->len)); + /* Add a new receive buffer to the ring. */ if (age_newbuf(sc, rxd, 0) != 0) { IFNET_STAT_INC(ifp, iqdrops, 1); @@ -2034,7 +2042,7 @@ /* The length of the first mbuf is computed last. */ if (count != 0) { - mp->m_len = AGE_RX_BYTES(le32toh(desc->len)); + mp->m_len = segsz; pktlen += mp->m_len; }