aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/fxp
diff options
context:
space:
mode:
authorPyun YongHyeon <yongari@FreeBSD.org>2010-05-14 17:39:28 +0000
committerPyun YongHyeon <yongari@FreeBSD.org>2010-05-14 17:39:28 +0000
commitf7a5f7371a284ce3fc46d633926bea6938f7ecc0 (patch)
tree851c684ff0d4a0c95a45b845571d639ab3e894f2 /sys/dev/fxp
parent01e3ef82d146f9f68949d9dd15195a2ec42d77d9 (diff)
downloadsrc-f7a5f7371a284ce3fc46d633926bea6938f7ecc0.tar.gz
src-f7a5f7371a284ce3fc46d633926bea6938f7ecc0.zip
If controller received bad frames make sure to update newly added
RFA. Also drop frames that have either CRC error or alignment error. Normally bad frames are not received at all. But controllers running in promiscuous mode will receive bad frames. 82557 will also receive bad frames to receive VLAN oversized frames. While I'm here mark RNR condition if driver happen to see RNR in RFA status and restart RU to receive frames again. Because driver checks all received frames in RX loop, RNR condition could be set in the middle of RX processing. Just relying on RNR interrupt was not enough. This change fixes "Memory modified after free" issue when fxp(4) is running as a member of if_bridge(4). Tested by: Larry Baird <lab <> gta dot com> MFC after: 5 days
Notes
Notes: svn path=/head/; revision=208084
Diffstat (limited to 'sys/dev/fxp')
-rw-r--r--sys/dev/fxp/if_fxp.c9
1 files changed, 7 insertions, 2 deletions
diff --git a/sys/dev/fxp/if_fxp.c b/sys/dev/fxp/if_fxp.c
index 006ec526b59a..079ecc1e82d9 100644
--- a/sys/dev/fxp/if_fxp.c
+++ b/sys/dev/fxp/if_fxp.c
@@ -1916,6 +1916,8 @@ fxp_intr_body(struct fxp_softc *sc, struct ifnet *ifp, uint8_t statack,
if ((status & FXP_RFA_STATUS_C) == 0)
break;
+ if ((status & FXP_RFA_STATUS_RNR) != 0)
+ rnr++;
/*
* Advance head forward.
*/
@@ -1942,9 +1944,12 @@ fxp_intr_body(struct fxp_softc *sc, struct ifnet *ifp, uint8_t statack,
total_len -= 2;
}
if (total_len < sizeof(struct ether_header) ||
- total_len > MCLBYTES - RFA_ALIGNMENT_FUDGE -
- sc->rfa_size || status & FXP_RFA_STATUS_CRC) {
+ total_len > (MCLBYTES - RFA_ALIGNMENT_FUDGE -
+ sc->rfa_size) ||
+ status & (FXP_RFA_STATUS_CRC |
+ FXP_RFA_STATUS_ALIGN)) {
m_freem(m);
+ fxp_add_rfabuf(sc, rxp);
continue;
}