summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiod Vallat <miod@cvs.openbsd.org>2014-06-13 21:06:25 +0000
committerMiod Vallat <miod@cvs.openbsd.org>2014-06-13 21:06:25 +0000
commit6cb6da5a8d2f3f488a4e5545482b1c3fe03b30bf (patch)
tree32fab32368422b4d3fb3cb9d6082f6761d919313
parenta8731620868fa745a41f9b4e4a93e317bd282d99 (diff)
Fix broken logic in sgec_rxintr() poorly duplicating some of ether_input()
checks, causing the rx ring pointer to stall as soon as an irrelevant frame is received when the intergace is in bpf+promiscuous or `all multicast' mode. Problem spotted and tracked down to the use of bpf by sebastia@. Hair pulling by me.
-rw-r--r--sys/arch/vax/if/sgec.c29
1 files changed, 5 insertions, 24 deletions
diff --git a/sys/arch/vax/if/sgec.c b/sys/arch/vax/if/sgec.c
index 88d6a649432..d0c2cb99237 100644
--- a/sys/arch/vax/if/sgec.c
+++ b/sys/arch/vax/if/sgec.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sgec.c,v 1.21 2013/11/27 08:56:31 mpi Exp $ */
+/* $OpenBSD: sgec.c,v 1.22 2014/06/13 21:06:24 miod Exp $ */
/* $NetBSD: sgec.c,v 1.5 2000/06/04 02:14:14 matt Exp $ */
/*
* Copyright (c) 1999 Ludd, University of Lule}, Sweden. All rights reserved.
@@ -413,6 +413,7 @@ zestart(ifp)
* Loop around and set it.
*/
totlen = 0;
+ orword = ZE_TDES1_FS;
for (m0 = m; m0; m0 = m0->m_next) {
error = bus_dmamap_load(sc->sc_dmat, sc->sc_xmtmap[idx],
mtod(m0, void *), m0->m_len, 0, 0);
@@ -423,9 +424,6 @@ zestart(ifp)
totlen += len;
/* Word alignment calc */
- orword = 0;
- if (totlen == len)
- orword = ZE_TDES1_FS;
if (totlen == m->m_pkthdr.len) {
if (totlen < ETHER_ADDR_LEN)
len += (ETHER_ADDR_LEN - totlen);
@@ -440,6 +438,7 @@ zestart(ifp)
if (++idx == TXDESCS)
idx = 0;
sc->sc_inq++;
+ orword = 0;
}
#ifdef DIAGNOSTIC
if (totlen != m->m_pkthdr.len)
@@ -495,27 +494,9 @@ sgec_rxintr(struct ze_softc *sc)
m->m_pkthdr.len = m->m_len = len;
eh = mtod(m, struct ether_header *);
#if NBPFILTER > 0
- if (ifp->if_bpf) {
+ if (ifp->if_bpf)
bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_IN);
- if ((ifp->if_flags & IFF_PROMISC) != 0 &&
- ((eh->ether_dhost[0] & 1) == 0) &&
- bcmp(sc->sc_ac.ac_enaddr, eh->ether_dhost,
- ETHER_ADDR_LEN) != 0) {
- m_freem(m);
- continue;
- }
- }
#endif
- /*
- * ALLMULTI means PROMISC in this driver.
- */
- if ((ifp->if_flags & IFF_ALLMULTI) &&
- ((eh->ether_dhost[0] & 1) == 0) &&
- bcmp(sc->sc_ac.ac_enaddr, eh->ether_dhost,
- ETHER_ADDR_LEN)) {
- m_freem(m);
- continue;
- }
ether_input_mbuf(ifp, m);
}
if (++sc->sc_nextrx == RXDESCS)
@@ -802,7 +783,7 @@ ze_setup(sc)
bcopy(enm->enm_addrlo, &zc->zc_setup[j], ETHER_ADDR_LEN);
j += 8;
ETHER_NEXT_MULTI(step, enm);
- if ((enm != NULL)&& (j == 128)) {
+ if (enm != NULL && j == sizeof(zc->zc_setup)) {
ifp->if_flags |= IFF_ALLMULTI;
break;
}