Module Name: src Committed By: jmcneill Date: Tue Nov 26 10:33:19 UTC 2019
Modified Files: src/sys/dev/pci: if_mcx.c Log Message: Fix IFF_ALLMULTI handling. To generate a diff of this commit: cvs rdiff -u -r1.6 -r1.7 src/sys/dev/pci/if_mcx.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/dev/pci/if_mcx.c diff -u src/sys/dev/pci/if_mcx.c:1.6 src/sys/dev/pci/if_mcx.c:1.7 --- src/sys/dev/pci/if_mcx.c:1.6 Mon Nov 18 04:40:05 2019 +++ src/sys/dev/pci/if_mcx.c Tue Nov 26 10:33:19 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: if_mcx.c,v 1.6 2019/11/18 04:40:05 nonaka Exp $ */ +/* $NetBSD: if_mcx.c,v 1.7 2019/11/26 10:33:19 jmcneill Exp $ */ /* $OpenBSD: if_mcx.c,v 1.33 2019/09/12 04:23:59 jmatthew Exp $ */ /* @@ -6205,8 +6205,11 @@ mcx_ioctl(struct ifnet *ifp, u_long cmd, { struct mcx_softc *sc = (struct mcx_softc *)ifp->if_softc; struct ifreq *ifr = (struct ifreq *)data; + struct ethercom *ec = &sc->sc_ec; uint8_t addrhi[ETHER_ADDR_LEN], addrlo[ETHER_ADDR_LEN]; - int s, i, error = 0; + struct ether_multi *enm; + struct ether_multistep step; + int s, i, flags, error = 0; s = splnet(); switch (cmd) { @@ -6214,8 +6217,10 @@ mcx_ioctl(struct ifnet *ifp, u_long cmd, case SIOCADDMULTI: if (ether_addmulti(ifreq_getaddr(cmd, ifr), &sc->sc_ec) == ENETRESET) { error = ether_multiaddr(&ifr->ifr_addr, addrlo, addrhi); - if (error != 0) + if (error != 0) { + splx(s); return (error); + } for (i = 0; i < MCX_NUM_MCAST_FLOWS; i++) { if (sc->sc_mcast_flows[i][0] == 0) { @@ -6238,7 +6243,7 @@ mcx_ioctl(struct ifnet *ifp, u_long cmd, error = ENETRESET; } - if (sc->sc_ec.ec_multicnt > 0) { + if (memcmp(addrlo, addrhi, ETHER_ADDR_LEN)) { SET(ifp->if_flags, IFF_ALLMULTI); error = ENETRESET; } @@ -6249,8 +6254,10 @@ mcx_ioctl(struct ifnet *ifp, u_long cmd, case SIOCDELMULTI: if (ether_delmulti(ifreq_getaddr(cmd, ifr), &sc->sc_ec) == ENETRESET) { error = ether_multiaddr(&ifr->ifr_addr, addrlo, addrhi); - if (error != 0) + if (error != 0) { + splx(s); return (error); + } for (i = 0; i < MCX_NUM_MCAST_FLOWS; i++) { if (memcmp(sc->sc_mcast_flows[i], addrlo, @@ -6269,10 +6276,23 @@ mcx_ioctl(struct ifnet *ifp, u_long cmd, sc->sc_extra_mcast--; if (ISSET(ifp->if_flags, IFF_ALLMULTI) && - (sc->sc_extra_mcast == 0) && - (sc->sc_ec.ec_multicnt == 0)) { - CLR(ifp->if_flags, IFF_ALLMULTI); - error = ENETRESET; + sc->sc_extra_mcast == 0) { + flags = 0; + ETHER_LOCK(ec); + ETHER_FIRST_MULTI(step, ec, enm); + while (enm != NULL) { + if (memcmp(enm->enm_addrlo, + enm->enm_addrhi, ETHER_ADDR_LEN)) { + SET(flags, IFF_ALLMULTI); + break; + } + ETHER_NEXT_MULTI(step, enm); + } + ETHER_UNLOCK(ec); + if (!ISSET(flags, IFF_ALLMULTI)) { + CLR(ifp->if_flags, IFF_ALLMULTI); + error = ENETRESET; + } } } break;