summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStuart Henderson <sthen@cvs.openbsd.org>2009-08-13 21:14:41 +0000
committerStuart Henderson <sthen@cvs.openbsd.org>2009-08-13 21:14:41 +0000
commitce1f2b4fdc3b042dec1a9751ad20b746a2ba2bcc (patch)
tree2e1794439528ed9a518bfaacff3b7efef6b79990
parent3af80e8da068c73661588621f782e0f00ed85d4d (diff)
Rewrite part of the promiscuous/multicast handling; tested by myself,
naddy@ and several tech@ readers. From Brad.
-rw-r--r--sys/dev/ic/fxp.c28
1 files changed, 10 insertions, 18 deletions
diff --git a/sys/dev/ic/fxp.c b/sys/dev/ic/fxp.c
index 4e55e1840d3..4514d6e3b3e 100644
--- a/sys/dev/ic/fxp.c
+++ b/sys/dev/ic/fxp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: fxp.c,v 1.97 2009/08/10 20:29:54 deraadt Exp $ */
+/* $OpenBSD: fxp.c,v 1.98 2009/08/13 21:14:40 sthen Exp $ */
/* $NetBSD: if_fxp.c,v 1.2 1997/06/05 02:01:55 thorpej Exp $ */
/*
@@ -1699,11 +1699,12 @@ fxp_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
void
fxp_mc_setup(struct fxp_softc *sc, int doit)
{
- struct fxp_cb_mcs *mcsp = &sc->sc_ctrl->u.mcs;
struct ifnet *ifp = &sc->sc_arpcom.ac_if;
+ struct arpcom *ac = &sc->sc_arpcom;
+ struct fxp_cb_mcs *mcsp = &sc->sc_ctrl->u.mcs;
struct ether_multistep step;
struct ether_multi *enm;
- int i, nmcasts;
+ int i, nmcasts = 0;
/*
* Initialize multicast setup descriptor.
@@ -1712,31 +1713,22 @@ fxp_mc_setup(struct fxp_softc *sc, int doit)
mcsp->cb_command = htole16(FXP_CB_COMMAND_MCAS | FXP_CB_COMMAND_EL);
mcsp->link_addr = htole32(-1);
- nmcasts = 0;
- if (!(ifp->if_flags & IFF_ALLMULTI)) {
+ if (ac->ac_multirangecnt > 0 || ac->ac_multicnt >= MAXMCADDR)
+ ifp->if_flags |= IFF_ALLMULTI;
+ else {
ETHER_FIRST_MULTI(step, &sc->sc_arpcom, enm);
while (enm != NULL) {
- if (nmcasts >= MAXMCADDR) {
- ifp->if_flags |= IFF_ALLMULTI;
- nmcasts = 0;
- break;
- }
-
- /* Punt on ranges. */
- if (bcmp(enm->enm_addrlo, enm->enm_addrhi,
- sizeof(enm->enm_addrlo)) != 0) {
- ifp->if_flags |= IFF_ALLMULTI;
- nmcasts = 0;
- break;
- }
bcopy(enm->enm_addrlo,
(void *)&mcsp->mc_addr[nmcasts][0], ETHER_ADDR_LEN);
nmcasts++;
+
ETHER_NEXT_MULTI(step, enm);
}
}
+
if (doit == 0)
return;
+
mcsp->mc_cnt = htole16(nmcasts * ETHER_ADDR_LEN);
/*