diff options
author | Stuart Henderson <sthen@cvs.openbsd.org> | 2009-08-13 21:14:41 +0000 |
---|---|---|
committer | Stuart Henderson <sthen@cvs.openbsd.org> | 2009-08-13 21:14:41 +0000 |
commit | ce1f2b4fdc3b042dec1a9751ad20b746a2ba2bcc (patch) | |
tree | 2e1794439528ed9a518bfaacff3b7efef6b79990 | |
parent | 3af80e8da068c73661588621f782e0f00ed85d4d (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.c | 28 |
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); /* |