summaryrefslogtreecommitdiffstats
path: root/sys/pci/if_dc.c
diff options
context:
space:
mode:
authorsilby <silby@FreeBSD.org>2003-10-19 23:05:19 +0000
committersilby <silby@FreeBSD.org>2003-10-19 23:05:19 +0000
commitfc5724e28ca9cb1b1295a7c3ea5c518db1e8aacc (patch)
tree133220321acfeb7a6e7fa835d8643357e126b130 /sys/pci/if_dc.c
parent4add8d9302f95e90df2c7b01613648b4f8c2a8a7 (diff)
downloadFreeBSD-src-fc5724e28ca9cb1b1295a7c3ea5c518db1e8aacc.zip
FreeBSD-src-fc5724e28ca9cb1b1295a7c3ea5c518db1e8aacc.tar.gz
Fix a problem where m_defrag would allocate a new mbuf to replace the
chain passed into dc_encap, which dc_start was unaware of. This caused the old (now invalid) mbuf to be passed to BPF_MTAP. Spotted by: Kenjiro Cho <kjc@csl.sony.co.jp>
Diffstat (limited to 'sys/pci/if_dc.c')
-rw-r--r--sys/pci/if_dc.c16
1 files changed, 8 insertions, 8 deletions
diff --git a/sys/pci/if_dc.c b/sys/pci/if_dc.c
index 6032703..b120f43 100644
--- a/sys/pci/if_dc.c
+++ b/sys/pci/if_dc.c
@@ -224,7 +224,7 @@ static void dc_acpi (device_t);
#endif
static struct dc_type *dc_devtype (device_t);
static int dc_newbuf (struct dc_softc *, int, int);
-static int dc_encap (struct dc_softc *, struct mbuf *);
+static int dc_encap (struct dc_softc *, struct mbuf **);
static void dc_pnic_rx_bug_war (struct dc_softc *, int);
static int dc_rx_resync (struct dc_softc *);
static void dc_rxeof (struct dc_softc *);
@@ -3266,7 +3266,7 @@ dc_dma_map_txbuf(arg, segs, nseg, mapsize, error)
* pointers to the fragment pointers.
*/
static int
-dc_encap(struct dc_softc *sc, struct mbuf *m_head)
+dc_encap(struct dc_softc *sc, struct mbuf **m_head)
{
struct mbuf *m;
int error, idx, chainlen = 0;
@@ -3283,15 +3283,15 @@ dc_encap(struct dc_softc *sc, struct mbuf *m_head)
* by all packets, we'll m_defrag long chains so that they
* do not use up the entire list, even if they would fit.
*/
- for (m = m_head; m != NULL; m = m->m_next)
+ for (m = *m_head; m != NULL; m = m->m_next)
chainlen++;
if ((chainlen > DC_TX_LIST_CNT / 4) ||
((DC_TX_LIST_CNT - (chainlen + sc->dc_cdata.dc_tx_cnt)) < 6)) {
- m = m_defrag(m_head, M_DONTWAIT);
+ m = m_defrag(*m_head, M_DONTWAIT);
if (m == NULL)
return (ENOBUFS);
- m_head = m;
+ *m_head = m;
}
/*
@@ -3301,12 +3301,12 @@ dc_encap(struct dc_softc *sc, struct mbuf *m_head)
*/
idx = sc->dc_cdata.dc_tx_prod;
error = bus_dmamap_load_mbuf(sc->dc_mtag, sc->dc_cdata.dc_tx_map[idx],
- m_head, dc_dma_map_txbuf, sc, 0);
+ *m_head, dc_dma_map_txbuf, sc, 0);
if (error)
return (error);
if (sc->dc_cdata.dc_tx_err != 0)
return (sc->dc_cdata.dc_tx_err);
- sc->dc_cdata.dc_tx_chain[idx] = m_head;
+ sc->dc_cdata.dc_tx_chain[idx] = *m_head;
bus_dmamap_sync(sc->dc_mtag, sc->dc_cdata.dc_tx_map[idx],
BUS_DMASYNC_PREWRITE);
bus_dmamap_sync(sc->dc_ltag, sc->dc_lmap,
@@ -3362,7 +3362,7 @@ dc_start(struct ifnet *ifp)
}
}
- if (dc_encap(sc, m_head)) {
+ if (dc_encap(sc, &m_head)) {
IF_PREPEND(&ifp->if_snd, m_head);
ifp->if_flags |= IFF_OACTIVE;
break;
OpenPOWER on IntegriCloud