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;

Reply via email to